Efficient Thumbnailing Here!

[code]#include <X11/Xlib.h>
#include <Imlib2.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
Display *display;
XWindowAttributes windowattr;
Imlib_Image image;
Imlib_Image icon;
int windowid, thumbwidth, thumbheight;
char *imageformat, *imagepath;
char *iconformat, *iconpath;
int w, h;

    if ( argc != 5 ) {
   puts("Usage: thumb WindowId ThumbWidth ThumbFile IconFile");
   return 1;

}
sscanf(argv[1], “%x”, &windowid);
sscanf(argv[2], “%d”, &thumbwidth);
imagepath = argv[3];
imageformat = strrchr(argv[3], ‘.’);
iconpath = argv[4];
iconformat = strrchr(argv[4], ‘.’);

    if ( (display = XOpenDisplay(NULL)) == NULL ) return 1;
    XGetWindowAttributes(display, windowid, &windowattr);
    thumbheight = (int)((float)windowattr.height / ((float)windowattr.width/(float)thumbwidth));

    imlib_context_set_anti_alias(1);
    imlib_context_set_display(display);
    imlib_context_set_visual(DefaultVisual(display, DefaultScreen(display)));
    imlib_context_set_colormap(DefaultColormap(display, DefaultScreen(display)));
    imlib_context_set_drawable(windowid);

    if ( 4*thumbwidth >= windowattr.width || 4*thumbheight >= windowattr.height ) {
            image = imlib_create_image_from_drawable((Pixmap)0, 0, 0,
                    windowattr.width, windowattr.height, 1);
            imlib_context_set_image(image);
            image = imlib_create_cropped_scaled_image(0, 0, windowattr.width, windowattr.height,
                    thumbwidth, thumbheight);
    } else {
            image = imlib_create_scaled_image_from_drawable((Pixmap)0, 0, 0,
                    windowattr.width, windowattr.height, 4*thumbwidth, 4*thumbheight, 1, 1);
            imlib_context_set_image(image);
            image = imlib_create_cropped_scaled_image(0, 0, 4*thumbwidth, 4*thumbheight,
                    thumbwidth, thumbheight);
    }

icon = imlib_load_image(argv[4]);
imlib_context_set_image(icon);
w = imlib_image_get_width();
h = imlib_image_get_height();
imlib_context_set_image(image);
imlib_blend_image_onto_image( icon, 0,
0, 0, w, h,
0, 0, w, h);
imlib_image_set_format(imageformat + 1);
imlib_save_image(argv[3]);

fprintf(stdout, “WindowStyle IconOverride, Icon %s\n”, argv[3]);
return 0;
} [/code]

this thumb function can have a window border like taviso thumb …convert -frame 1x1…

sorry for my bad english :cry:

The screen height and width can also be obtained by $[vp.width] and $[vp.height]

Hi all,

Isr wanted a frame around his thumbnails. Here’s a quick’n’dirty sort of implementation. Thanks to Sascha and Pem for the groundwork and modifications. :slight_smile:

(I should also add that since I place my icons along the bottom of the screen rather than down the side, the third argument of this example is ThumbHeight not ThumbWidth.)

#include <X11/Xlib.h>
#include <Imlib2.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
        Display *display;
        XWindowAttributes windowattr;
        Imlib_Image image;
        Imlib_Image icon;
        int windowid, thumbwidth, thumbheight;
        char *imageformat, *imagepath;
        char *iconformat, *iconpath;
   int w, h;

        if ( argc != 5 ) {
       puts("Usage: thumb WindowId ThumbHeight ThumbFile IconFile");
       return 1;
   }
        sscanf(argv[1], "%x", &windowid);
        sscanf(argv[2], "%d", &thumbheight);
        imagepath = argv[3];
        imageformat = strrchr(argv[3], '.');
        iconpath = argv[4];
        iconformat = strrchr(argv[4], '.');


        if ( (display = XOpenDisplay(NULL)) == NULL ) return 1;
        XGetWindowAttributes(display, windowid, &windowattr);
        thumbwidth = (int)((float)windowattr.width / ((float)windowattr.height/(float)thumbheight));

        imlib_context_set_anti_alias(1);
        imlib_context_set_display(display);
        imlib_context_set_visual(DefaultVisual(display, DefaultScreen(display)));
        imlib_context_set_colormap(DefaultColormap(display, DefaultScreen(display)));
        imlib_context_set_drawable(windowid);

        if ( 4*thumbwidth >= windowattr.width || 4*thumbheight >= windowattr.height ) {
                image = imlib_create_image_from_drawable((Pixmap)0, 0, 0,
                        windowattr.width, windowattr.height, 1);
                imlib_context_set_image(image);
                image = imlib_create_cropped_scaled_image(0, 0, windowattr.width, windowattr.height,
                        thumbwidth, thumbheight);
        } else {
                image = imlib_create_scaled_image_from_drawable((Pixmap)0, 0, 0,
                        windowattr.width, windowattr.height, 4*thumbwidth, 4*thumbheight, 1, 1);
                imlib_context_set_image(image);
                image = imlib_create_cropped_scaled_image(0, 0, 4*thumbwidth, 4*thumbheight,
                        thumbwidth, thumbheight);
        }
   icon = imlib_load_image(argv[4]);
        imlib_context_set_image(icon);
   w = imlib_image_get_width();
   h = imlib_image_get_height();

        imlib_context_set_image(image);
   imlib_blend_image_onto_image(   icon, 0,
               0, 0, w, h,
               0, 0, w, h);
   imlib_context_set_color(
	       0,	      /*red   (0-255)*/
	       0,	      /*green (0-255)*/
	       0,	      /*blue  (0-255)*/
	       255);	      /*alpha (0-255)*/
   imlib_image_draw_rectangle(
	       0, 0, thumbwidth, thumbheight);
        imlib_image_set_format(imageformat + 1);
        imlib_save_image(argv[3]);

   fprintf(stdout, "WindowStyle IconOverride, Icon %s\n", argv[3]);
        return 0;
}

Regards,

Rob

Is there a setting in the script that determines the placement of the thumbnails, or should I be looking in a different file? I’m trying to switch the thumbnails to the right side of the screen (my terminal goes on the left :blush: )

That is specified in your fvwm config, the script has nothing to do with that (it merely generates the image).

Thanks for the help. By the way, your config (clean and (sometimes) green) is awsome stonecrest.

Edit: for other noobs like me… “man FvwmIconBox”

If I don’t EWMHMiniIconOverride the big icon, then there are no icons on my thumbnails, and I get this error:

[code]***** Imlib2 Developer Warning ***** :
This program is calling the Imlib call:

imlib_blend_image_onto_image();

With the parameter:

source_image

being NULL. Please fix your program.[/code]

If I EWMHMiniIconOverride, than it’s ok. Why isn’t thumb.c recognizing regular programs Icons?!?!?!?

Because there’s a “clash” (you can think of it like that). So in order for EWMH-based applications to be told that you want to override their icon with your own, they have to be told.

– Thomas Adam

is it possible to create the frame around the images instead of overwriting the edge of the image?

for example:

  • convert gets a 83 pixel image, adds the frame around the image and you get a 85 pixel image.
  • thumb gets a 83 pixel image, writes the edge over the edge of the image and the image stays at 83 pixel.

I’d like to have the frame around the thumbnail without overwriting some of the image.

Try this:

  1. get the _NET_WM_ICON atom like e.g. “xprop _NET_WM_ICON” does
  2. convert the data to an image (example in perl):

Try somethink like his:

  1. create a new image:

image2 = imlib_create_image(thumbwidth+2, thumbheight+2); imlib_context_set_image(image2);
2. draw the rectangle

imlib_context_set_color(0, 0, 0, 255); imlib_image_fill_rectangle(0, 0, thumbwidth+2, thumbheight+2);
3. copy the thumbnail onto the new image:

       imlib_blend_image_onto_image(image, 1, 0, 0, thumbwidth, thumbheight, 1, 1, thumbwidth, thumbheight);

thanks, sascha. it worked fine.

@jsosic: You can use this example to modify your thumbnailing code:

[code]/* compile: gcc -Wall -Werror -o ewmhIcon ewmhIcon.c imlib2-config --cflags imlib2-config --libs /
/
usage: ./ewmhIcon 0x3000006 icon.png */

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <Imlib2.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
Display *display;
int windowid, format, width, height;
unsigned long nitems, bytesafter, *ret;
Atom net_wm_icon, req_type;
Imlib_Image image;
DATA32 *imagedata;

    if ( argc != 3 ) return 1;
    sscanf(argv[1], "%x", &windowid);

    if ( (display = XOpenDisplay(NULL)) == NULL ) return 1;
    net_wm_icon = XInternAtom(display, "_NET_WM_ICON", 1);

    /* get width */
    XGetWindowProperty(display, windowid, net_wm_icon, 0, 1, 0, XA_CARDINAL,
                    &req_type, &format, &nitems, &bytesafter, (unsigned char **)&ret);
    if ( req_type == None ) return 1;
    width = ret[0];
    XFree(ret);

    /* get height */
    XGetWindowProperty(display, windowid, net_wm_icon, 1, 1, 0, XA_CARDINAL,
                    &req_type, &format, &nitems, &bytesafter, (unsigned char **)&ret);
    if ( req_type == None ) return 1;
    height = ret[0];
    XFree(ret);

    /* get image data */
    XGetWindowProperty(display, windowid, net_wm_icon, 2, width * height, 0, XA_CARDINAL,
                    &req_type, &format, &nitems, &bytesafter, (unsigned char **)&ret);
    if ( req_type == None ) return 1;

    image = imlib_create_image(width, height);
    imlib_context_set_image(image);
    imlib_image_set_has_alpha(1);
    imagedata = imlib_image_get_data();

    memcpy(imagedata, ret, width * height * 4);
    XFree(ret);

    imlib_image_put_back_data(imagedata);
    imlib_image_set_format(strrchr(argv[2], '.') + 1);
    imlib_save_image(argv[2]);

    return 0;

}
[/code]

Hi !

I am a very big newbie with fvwm … I tried to copy these lines into my .fvwm2rc, but It is not working when I am minimizing the window.

I really don’t know much about fvwm (& have linux since sept 05), to help us, could you post the content of your .fvwm2rc ?? (in order to make it work this mini minimizing screenshot)

I’ll copy paste it, and try to understand …
Sorry of my lack of knowledge :frowning:

Greetings,

Thank you very much !!

Patrick

well, i use the thumbnails as miniicons, not as icons, but it should not be too hard to change it.

#### generates a thumbnail of the current window as it's miniicon (requires imlib2)
SetEnv fvwm_icon_width 83
DestroyFunc Thumbnail
AddToFunc Thumbnail
+ I Raise
+ I SetEnv MiniIcon-$[w.id] $[w.MiniIconFile]
+ I ThisWindow (!Shaded, Iconifiable, !Iconic) PipeRead \
    "$[FVWM_USERDIR]/scripts/thumb $[w.id] $[fvwm_icon_width] $[FVWM_USERDIR]/miniicon.tmp.$[w.id].png \
	&& echo WindowStyle EWMHMiniIconOverride, MiniIcon $[FVWM_USERDIR]/miniicon.tmp.$[w.id].png \
    || echo Nop"
+ I Iconify

#### deletes the thumbnail (by using FvwmEvent)
DestroyFunc DeThumbnail
AddToFunc DeThumbnail
+ I PipeRead "echo WindowStyle EWMHMiniIconOverride, MiniIcon Nop"
+ I Exec rm -f $[FVWM_USERDIR]/miniicon.tmp.$[w.id].png
+ I UnsetEnv MiniIcon-$[w.id]
DestroyModuleConfig FvwmEvent: *
*FvwmEvent: deiconify DeThumbnail

you must have the executable “thumb” in ~/.fvwm/scripts and use “thumbnail” instead of “minimize” for the button you want to use to create the thumbnails.

Sascha wrote:

:smiley: Ah, much neater than my hatchet job! Thanks, Sascha.

Rob

Hey guys,
thanks for your work! And do you have any idea how i should go about adding a bit of transparency to the thumbnails?

Thanks

You can add something like “IconAlpha 60” to your colorset. i.e.

Colorset 1 fg #888888, bg #000000, fgsh #000000, NoShape, RootTransparent, Tint #283e5e 70, IconAlpha 60

Thanks stonecrest, didn’t realize fvwm was able to do this!! :slight_smile:

Hi,

First, thank you very much for yoru information !!
I am newbie since sept 2005 in linux; I am sorry asking this very easy question concerning the thumbnails … :
I downloaded the imlib2 files as tar.gz
from the net
there is one imlib2 and one loader. I unpacked them with mc, ok , but in order to install them …
I did ./configure but it’s not workign
(./install gives no results)
I got an error message from ./configure
What should I do ?

I tried to do:
apt-get -f install imlib2… stuffs but not existing in ubuntu breezy

Would you know how to install this wonderful imlib2 ?

Sorry for the newbie question again

thank you very much ,

Patrick
I am

On debian you need libimlib2 and libimlib2-dev:
apt-get install libimlib2 libimlib2-dev