Discussion:
[Gtk-sharp-list] How can I save a cairo imagesurface as a pixbuf
alanb
2008-12-22 17:51:44 UTC
Permalink
I have a treeview and I want to store dynamically generated images in one of
its columns. Reading the treeview tutorial I see that I need my image as a
pixbuf. I am drawing the images using Cairo, all I can see in the
imagesurface API is to save as a png file directly with no access to its
underlying stream which I could use. So how can I convert a Cairo image to a
pixbuf?

If I use a Gdk.pixmap instead and draw to it, again how do I convert it to a
pixbuf?

thanks
Alan
--
View this message in context: http://www.nabble.com/How-can-I-save-a-cairo-imagesurface-as-a-pixbuf-tp21131994p21131994.html
Sent from the Mono - Gtk# mailing list archive at Nabble.com.
Andy Selvig
2008-12-24 20:54:49 UTC
Permalink
Alan-

Try creating a Gtk.DrawingArea, then use Gdk.CairoHelper to create a Cairo
context to draw to. Then you can use Gdk.Pixbuf.FromDrawable to create the
pixbuf. Something like:

Gtk.DrawingArea area = new Gtk.DrawingArea();
using (Context cr = Gdk.CairoHelper.Create(area.GdkWindow))
{

}
Post by alanb
I have a treeview and I want to store dynamically generated images in one of
its columns. Reading the treeview tutorial I see that I need my image as a
pixbuf. I am drawing the images using Cairo, all I can see in the
imagesurface API is to save as a png file directly with no access to its
underlying stream which I could use. So how can I convert a Cairo image to a
pixbuf?
If I use a Gdk.pixmap instead and draw to it, again how do I convert it to a
pixbuf?
thanks
Alan
--
http://www.nabble.com/How-can-I-save-a-cairo-imagesurface-as-a-pixbuf-tp21131994p21131994.html
Sent from the Mono - Gtk# mailing list archive at Nabble.com.
_______________________________________________
http://lists.ximian.com/mailman/listinfo/gtk-sharp-list
Andy Selvig
2008-12-24 21:05:01 UTC
Permalink
Oops, trouble typing code into GMail. Let's finish...

Gtk.DrawingArea area = new Gtk.DrawingArea();
using (Context cr = Gdk.CairoHelper.Create(area.GdkWindow))
{
// draw the image with Cairo
}
Gdk.Pixbuf pixbuf = Gdk.Pixbuf.FromDrawable(area.GdkWindow,
Gdk.Colormap.System, ...);

I haven't used this exact method, but I don't see why it wouldn't work.
There also might be a better way that I'm not seeing.
Post by Andy Selvig
Alan-
Try creating a Gtk.DrawingArea, then use Gdk.CairoHelper to create a Cairo
context to draw to. Then you can use Gdk.Pixbuf.FromDrawable to create the
Gtk.DrawingArea area = new Gtk.DrawingArea();
using (Context cr = Gdk.CairoHelper.Create(area.GdkWindow))
{
}
Post by alanb
I have a treeview and I want to store dynamically generated images in one of
its columns. Reading the treeview tutorial I see that I need my image as a
pixbuf. I am drawing the images using Cairo, all I can see in the
imagesurface API is to save as a png file directly with no access to its
underlying stream which I could use. So how can I convert a Cairo image to a
pixbuf?
If I use a Gdk.pixmap instead and draw to it, again how do I convert it to a
pixbuf?
thanks
Alan
--
http://www.nabble.com/How-can-I-save-a-cairo-imagesurface-as-a-pixbuf-tp21131994p21131994.html
Sent from the Mono - Gtk# mailing list archive at Nabble.com.
_______________________________________________
http://lists.ximian.com/mailman/listinfo/gtk-sharp-list
Christian Hoff
2008-12-25 08:54:38 UTC
Permalink
Why don't you use a custom cell renderer? Using a CellRendererPixbuf and
converting all your images into a pixbuf takes much more time. I've
attached my EAN13Renderer class. It draws the images directly into the
graphics context using cairo in the Render() method.

Christian
Post by Andy Selvig
Alan-
Try creating a Gtk.DrawingArea, then use Gdk.CairoHelper to create a
Cairo context to draw to. Then you can use Gdk.Pixbuf.FromDrawable to
Gtk.DrawingArea area = new Gtk.DrawingArea();
using (Context cr = Gdk.CairoHelper.Create(area.GdkWindow))
{
}
I have a treeview and I want to store dynamically generated images in one of
its columns. Reading the treeview tutorial I see that I need my image as a
pixbuf. I am drawing the images using Cairo, all I can see in the
imagesurface API is to save as a png file directly with no access to its
underlying stream which I could use. So how can I convert a Cairo image to a
pixbuf?
If I use a Gdk.pixmap instead and draw to it, again how do I convert it to a
pixbuf?
thanks
Alan
--
http://www.nabble.com/How-can-I-save-a-cairo-imagesurface-as-a-pixbuf-tp21131994p21131994.html
Sent from the Mono - Gtk# mailing list archive at Nabble.com.
_______________________________________________
http://lists.ximian.com/mailman/listinfo/gtk-sharp-list
------------------------------------------------------------------------
_______________________________________________
http://lists.ximian.com/mailman/listinfo/gtk-sharp-list
Christian Hoff
2008-12-25 08:58:46 UTC
Permalink
Sorry, forgot to attach the class :-)
Post by Christian Hoff
Why don't you use a custom cell renderer? Using a CellRendererPixbuf and
converting all your images into a pixbuf takes much more time. I've
attached my EAN13Renderer class. It draws the images directly into the
graphics context using cairo in the Render() method.
Christian
Post by Andy Selvig
Alan-
Try creating a Gtk.DrawingArea, then use Gdk.CairoHelper to create a
Cairo context to draw to. Then you can use Gdk.Pixbuf.FromDrawable to
Gtk.DrawingArea area = new Gtk.DrawingArea();
using (Context cr = Gdk.CairoHelper.Create(area.GdkWindow))
{
}
I have a treeview and I want to store dynamically generated images in one of
its columns. Reading the treeview tutorial I see that I need my image as a
pixbuf. I am drawing the images using Cairo, all I can see in the
imagesurface API is to save as a png file directly with no access to its
underlying stream which I could use. So how can I convert a Cairo image to a
pixbuf?
If I use a Gdk.pixmap instead and draw to it, again how do I convert it to a
pixbuf?
thanks
Alan
alan battersby
2008-12-30 19:03:14 UTC
Permalink
Christian,

Just got round to implementing a cell renderer. Thanks a lot it works a
treat.

Alan
Post by Andy Selvig
Post by Christian Hoff
Why don't you use a custom cell renderer? Using a CellRendererPixbuf
and converting all your images into a pixbuf takes much more time.
I've attached my EAN13Renderer class. It draws the images directly
into the graphics context using cairo in the Render() method.
Christian
------------------------------------------------------------------------
_______________________________________________
http://lists.ximian.com/mailman/listinfo/gtk-sharp-list
Christian Hoff
2008-12-25 18:09:26 UTC
Permalink
You're right the effect only shows up if you have a large number of
rows. But not storing the images as a pixbuf leads to a considerable
performance improvement. I used my EAN13 class in a treeview that had
about 10.000 rows. In earlier versions it was derived from
CellRendererPixbuf and the load was awfully slow(about 30 seconds!)
because Gtk+ renders not just the visible cells, but instead all of them.

That's why I tested the approach to subclass directly from CellRenderer
and create the image in the render method using Cairo. And suddenly
everything was 10 times faster(yes it was really that much a
difference). BTW the CellRendererPixbuf uses cairo as well:

cr = gdk_cairo_create (window);

gdk_cairo_set_source_pixbuf (cr, pixbuf, pix_rect.x, pix_rect.y);
gdk_cairo_rectangle (cr, &draw_rect);
cairo_fill (cr);

cairo_destroy (cr);

Christian
Using a CellRendererPixbuf and converting all your images into a pixbuf takes much more time.
Are you sure? Yes, it would definitely take more time up front, but it
seems like in general it would be faster to have them stored as
pixbufs that the renderer could just dump on to the screen. Doesn't
this method force every single cell to be freshly drawn every time the
tree view is rendered? Cairo is great, but speed isn't exactly its
thing.
In the end, it probably doesn't matter much unless you have a
ridiculous number of cell shown.
Andy Selvig
2008-12-28 22:02:46 UTC
Permalink
You're right the effect only shows up if you have a large number of rows. But not storing the images as a pixbuf leads to a considerable performance improvement. I used my EAN13 class in a treeview that had about 10.000 rows. In earlier versions it was derived from CellRendererPixbuf and the load was awfully slow(about 30 seconds!) because Gtk+ renders not just the visible cells, but instead all of them.
But how many unique icons are there? If 5000 of the cells share the
same icon, shouldn't it only need to be generated once then stored as
a pixbuf and displayed for the rest of them?
cr = gdk_cairo_create (window);
gdk_cairo_set_source_pixbuf (cr, pixbuf, pix_rect.x, pix_rect.y);
gdk_cairo_rectangle (cr, &draw_rect);
cairo_fill (cr);
cairo_destroy (cr);
That's interesting. Good to know.
Loading...