GdkPixbuf and transparency



Hi all,

I'm having problems with GdkPixbufs and source-transparency in GTK+ 1.3.3...

As a bit of background: I'm trying to persuade the GTK+ team to implement a
method of rendering directly from a pixbuf to an image (without going via a
pixmap). Their current view appears to be that this should never be neccessary
- you should be able to do everything using pixbufs. I'm almost certain that
they are mistaken and that for at least some applications pixbufs will be a lot
slower. Nevertheless, it's not much use for me to just assert that this is the
case without some hard data. Consequently, I'm trying to implement a parallel
algorithm for the application that I help develop (Slash'EM) to work with
pixbufs (an algorithm already exists for images using GdkImage).

My problem is that I can't seem to get gdk_pixbuf_composite() to work as
expected. It's entirely possible that I'm doing something stupid, but I can't
see what.

I'll use "raster" as a generic term to represent a 2D array of pixels since
image might be confusing.

The basic setup in Slash'EM is that we have a tileset which is just a large
static raster loaded from disk which contains a 2D array of tiles. When we want
to update a cell on the map window, we take two tiles (a background and a
foreground tile) and overlay them in a temporary raster before this is then
copied to the master raster (the expose handler then updates the screen from
this in due course). Actually, because both background and foreground tiles have
transparent pixels it would be more correct to say that we overlay both of them
on a black background.

My current algorithm to do this is as follows:

1. Clear the temporary raster with memset() to zero:

   memset(gdk_pixbuf_get_pixels(tmp_pixbuf), 0,
     gdk_pixbug_get_height(tmp_pixbuf) * gdk_pixbuf_get_rowstride(tmp_pixbuf));

2. Overlay the background tile with gdk_pixbuf_copy_area():

   gdk_pixbuf_copy_area(tile_pixbuf, srcx, srcy, width, height,
     tmp_pixbuf, dstx, dsty);

   srcx and srcy select the correct tile from the tileset stored in tile_pixbuf.
   dstx and dsty are normally zero and width and height are normally the size
   of the temporary raster (the same as the tiles).

3. Force all pixels to opaque (not sure if this is neccessary):

   for(j=0;j<Tile->unit_height;j++)
       for(i=0;i<Tile->unit_width;i++) {
           nh_pixbuf_get_pixel(i, j, rgba);
           rgba[3] = 255;
           nh_pixbuf_put_pixel(i, j, rgba);
       }

   where rgba is an array of 4 guchars, nh_pixbuf_get_pixel() and
   nh_pixbuf_put_pixel() do the obvious. unit_height and unit_width are the
   sizes of the tiles.

4. Overlay the foreground tile with pdk_pixbuf_composite():

   gdk_pixbuf_composite(tile_pixbuf, tmp_pixbuf, dstx, dsty, width,
     height, -srcx, -srcy, 1.0, 1.0, GDK_INTERP_NEAREST, 255.0);

5. Copy to the master raster with gdk_pixbuf_copy_area():

   gdk_pixbuf_copy_area(tmp_pixbuf, 0, 0, gdk_pixbug_get_width(tmp_pixbuf),
     gdk_pixbug_get_height(tmp_pixbuf), xshm_map_pixbuf, dest_x, dest_y);

   where xshm_map_pixbuf is the master copy of the map and dest_x and dest_y
   are the coordinates of the relevant cell.

The expose handler then updates the server-side copy of the map like this:

gdk_gc_set_clip_region(gc, xshm.dirty);
gdk_pixbuf_render_to_drawable(xshm_map_pixbuf, xshm.pixmap, gc,
  0, 0, 0, 0, xshm.map_width, xshm.map_height,
  GDK_RGB_DITHER_NORMAL, 0, 0);

where xshm.dirty is a region consisting of the union of all cells that have
been modified since the expose handler was last called.

The problem (finally) is that the background tiles look perfect but the
foreground tiles are just silhouettes in a dithered, desaturated green.
The green looks like it could well be the colour that we use to indicate
transparancy in the tileset. The background tile is correctly visible in the
transparent parts of the foreground tile.

Note that if I replace step 4 with a call to gdk_pixbuf_copy_area() then all
works as expected (we get opaque foreground tiles).

I would be very grateful for any help you may be able to give me.

-- 
Ali Harlow                              Email: ali avrc city ac uk
Research programmer                     Tel:   (020) 7477 8000 X 4348
Applied Vision Research Centre          Intl: +44 20 7477 8000 X 4348
City University                         Fax:   (020) 7505 5515
London                                  Intl: +44 20 7505 5515




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]