Re: Drawing higher depth images



David Necas (Yeti) wrote:
Is it possible to use Gdk drawing functions (gdk_draw_arc(),
etc.) to draw images of higher depth than system and save
them?

I can save GdkPixbufs.  If there were drawing primitives in
gdk-pixbuf, it would be everything I need.  However I can
draw only on GdkDrawables.

To use gdk_pixbuf_get_from_drawable() I need a colormap.

To create a colormap I need a visual.

And I can get only visuals with depths returned by
gdk_query_depths(), that is system visual.  If it's 16 or
even 8 bpp, I have to use that.

Or is there any other method to draw true color images?
(Except using other libraries like Cairo, which currently is
no option for me).
There's one trick:
1. Create a pixmap with depth of 32.
2. Create gc for the pixmap.
3. Set the 32-bit colour you want with gdk_gc_set_foreground() (0xAABBGGRR for the little-endian boxes, 0xRRGGBBAA for the big-endian ones).
4. Use any some GDK drawing primitives to draw on pixmap.
5. Create image from pixmap.
6. Create pixbuf with alpha-channel from image.
7. Do whatever you want with pixbuf.

I think (didn't check, however, with a new GDK) that you'll not be able to draw a Pango layout to such pixmap with gdk_draw_layout(). The possible solution is to use X11 calls (they should work ok) or to render layout manually.

If you want to directly draw to such pixbuf with GDK calls, you can create shared pixmap with XShm extension. In this case steps will be like this:
1. Create shared pixmap width depth of 32 via MIT-SHM extension.
2. Create foreign pixmap to make GDK happy.
3. == 2 from the steps above
4. == 3 ^^^
5. == 4 ^^^
6. Create pixbuf from the data, stored in shared memory.
7. Do whatever you want with both pixbuf and pixmap.
This will work in the local case (application and X server run on the same box).

PS: you also can try to setup another X server with framebuffer in the system memory, but this is somewhat exotic.

PPS: as John said you can try libart (if this is more suitable option than cairo), but with GnomeCanvas. Canvas can be easily hacked (guys, please dont flame on the word *easily*) in the way to redirect output to the pixbuf. The main advantage in this case is that you can draw text in the modern way.

PPPS: sorry for the late reply :)

--- the sample
#include <gdk/gdk.h>

#define WIDTH   128
#define HEIGHT  128

int
main(int argc, char **argv)
{
        GdkGC           *gc;
        GdkColor        colour;
        GdkPixmap       *pixmap;
        GdkImage        *image;
        GdkPixbuf       *pixbuf;

        gdk_init(&argc, &argv);

        pixmap = gdk_pixmap_new(NULL, WIDTH,HEIGHT, 32);
        g_return_val_if_fail(pixmap != NULL, 1);

        gc = gdk_gc_new(pixmap);
        g_return_val_if_fail(gc != NULL, 1);

        colour.pixel = 0;
        gdk_gc_set_foreground(gc, &colour);
        gdk_draw_rectangle(pixmap, gc, TRUE, 0,0, -1,-1);

        colour.pixel = 0xff000000;	/* black */
        gdk_gc_set_foreground(gc, &colour);
        gdk_draw_line(pixmap, gc, 0,0, WIDTH/2,HEIGHT/2);

        colour.pixel = 0xffff0000;	/* blue */
        gdk_gc_set_foreground(gc, &colour);
        gdk_draw_line(pixmap, gc, WIDTH,0, WIDTH/2,HEIGHT/2);

        colour.pixel = 0xff00ff00;	/* green */
        gdk_gc_set_foreground(gc, &colour);
        gdk_draw_line(pixmap, gc, 0,HEIGHT, WIDTH/2,HEIGHT/2);

        colour.pixel = 0xff0000ff;	/* red */
        gdk_gc_set_foreground(gc, &colour);
        gdk_draw_line(pixmap, gc, WIDTH,HEIGHT, WIDTH/2,HEIGHT/2);

        colour.pixel = 0xff80CCff;
        gdk_gc_set_foreground(gc, &colour);
gdk_draw_arc(pixmap, gc, FALSE, 10,10, WIDTH-20,HEIGHT-20, 0,360*64);

        image = gdk_image_get(pixmap, 0,0, WIDTH,HEIGHT);
        g_return_val_if_fail(image != NULL, 1);

        pixbuf = gdk_pixbuf_new_from_data(
                image->mem,
                GDK_COLORSPACE_RGB,
                TRUE,
                8,
                image->width, image->height,
                image->bpl,
                NULL, NULL
        );
        g_return_val_if_fail(pixbuf != NULL, 1);

        gdk_pixbuf_save(pixbuf, "test.png", "png", NULL, NULL);

        return 0;
}
the sample ---

	Olexiy



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