Re: Drawing higher depth images
- From: Olexiy Avramchenko <olexiy ctech cn ua>
- To: "David Necas (Yeti)" <yeti physics muni cz>
- Cc: gtk-list gnome org
- Subject: Re: Drawing higher depth images
- Date: Tue, 12 Jul 2005 17:11:38 +0300
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]