GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Wed Sep 17, 2014 1:32 am

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Pain in painting a colour map
PostPosted: Tue Jan 31, 2012 3:34 pm 
Offline
Familiar Face

Joined: Wed Aug 17, 2011 12:20 pm
Posts: 20
I want to display a colour map as a part of a GTK+ window. The colour map is a colour coded visualisation of a 2D array, every array entry as a pixel. It's of a significant size, reaches into the megapixels range.

My first attempt works, but is awkward and slow. I used a GtkDrawingArea to display the map, and used Cairo to paint the pixels in the expose handler. I could not find any method in Cairo to colour single pixels, so I used cairo_rectangle() / cairo_fill(). This way, the three calls to cairo (setting colour is the third) per pixel take up more than 90% of all the execution time in the expose handler. There must be more appropriate ways of doing this. I can see two possible approaches:

A.) There is a Cairo way of painting a pixel in a given colour that is fast (bypassing all the rectangle filling code in Cairo). This one would be convenient because I don't need to change much in my code. But I cannot find anything in the Cairo API documentation.

B.) The painting is actually performed on a background pixmap, which the expose handler only copies into the drawing area. As a variation, a GtkImage could be used to display the background pixmap instead of the GtkDrawingArea.

Any suggestions on which way to go? B seems to only relocate the problem, as I'm not sure how to draw pixels into, say, a GdkPixbuf. Would I need to low-level manipulate the pixel data?

Cheers Peter


Top
 Profile  
 
 Post subject: Re: Pain in painting a colour map
PostPosted: Tue Jan 31, 2012 7:57 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hi.

There are quite a few possible ways of achieving what you want. What would be the best one depends on what exactly does your application need to do.

These are some of the options I came up with:
  1. Create GdkPixbuf that fits the source array, set pixels to their values and display that in GtkImage (pros: fast, simple cons: GdkPixbuf cannot be scaled (different display sizes will require different GdkPixbuf)
  2. Create cairo_image_surface_t that fits the original array, set pixels to their values then draw this in expose-event handler of GtkDrawingArea (pros: fast, same source surface can be scaled to fit various dimensions of GtkDrawingArea cons: when scaling, some defects may occur due to interpolation)

Oh, I almost forgot to tell you: you can set individual pixels in GdkPixbuf or in cairo_image_surface_t. Both are stored in memory in similar (but incompatible) layouts that are described here (for GdkPixbuf) and here (for cairo_image_surface_t).

Hope this info helps a bit.

Cheers,
Tadej


Top
 Profile  
 
 Post subject: Re: Pain in painting a colour map
PostPosted: Wed Feb 01, 2012 2:38 pm 
Offline
Familiar Face

Joined: Wed Aug 17, 2011 12:20 pm
Posts: 20
Yes, is does help, thank you very much, as I will also try your suggestion using Cairo and compare. The solution with the GtkImage I also got working meanwhile, after some hunting around I found an example put_pixel() function in the GdkPixbuf library documentation.
What caused me some trouble though is some bug in either the documentation or that example code: It assumes there is an alpha channel, even though the only pixbuf type the library knows (according to docs) is GDK_COLORSPACE_RGB which does not have an alpha channel (at least not in my version 2.18). Accordingly the code, when painting the pixel at x,y, would also overwrite the red channel of pixel ((x+1) mod width), (y+x/width) with the passed value for the alpha channel.
Mysteriously the example code ASSERTs n_channel == 4, whereas a GdkPixbuf created with the parameter GDK_COLORSPACE_RGB has n_channel == 3 (causing the assertion to fail). This in fact seems to indicate that, instead of introducing a new type GDK_COLORSPACE_RGBA, the GDK maintainers just changed the operation mode of GDK_COLORSPACE_RGB, which - if true - I'd call a really stupid decision.
Whatever really happened, maybe some enlightened one can fix the docs or the example code, there is nothing worse than erroneous documentation.

Cheers Peter


Top
 Profile  
 
 Post subject: Re: Pain in painting a colour map
PostPosted: Wed Feb 01, 2012 8:02 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hi.

perot wrote:
What caused me some trouble though is some bug in either the documentation or that example code: It assumes there is an alpha channel, even though the only pixbuf type the library knows (according to docs) is GDK_COLORSPACE_RGB which does not have an alpha channel (at least not in my version 2.18). Accordingly the code, when painting the pixel at x,y, would also overwrite the red channel of pixel ((x+1) mod width), (y+x/width) with the passed value for the alpha channel.
Mysteriously the example code ASSERTs n_channel == 4, whereas a GdkPixbuf created with the parameter GDK_COLORSPACE_RGB has n_channel == 3 (causing the assertion to fail). This in fact seems to indicate that, instead of introducing a new type GDK_COLORSPACE_RGBA, the GDK maintainers just changed the operation mode of GDK_COLORSPACE_RGB, which - if true - I'd call a really stupid decision.
Whatever really happened, maybe some enlightened one can fix the docs or the example code, there is nothing worse than erroneous documentation.


I think gdk-pixbuf doesn't separate RGB and RGBA colorspaces. RGB is "3-channel RGB" and RGBA is "4-channel RGB" (this has been so from the start). Also, if you look at the docs for gdk_pixbuf_new(), you'll see that alpha channel creation is specified by additional parameter and is not part of colorspace definition. Example code explicitly states that is meant to be used on 4-channel RGB images (that is, RGBA), so nothing is wrong there. But I agree that things are a bit awkward when it comes to naming.

Cheers,
Tadej


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: Yahoo [Bot] and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group