You might also have a look at go_cairo_convert_data_to_pixbuf( http://svn.gnome.org/viewvc/goffice/trunk/goffice/utils/go-cairo.c?revision=1884&view=markup ) which works when there is an alpha channel (things are not as simple as exchanging the R and B bytes): /** * go_cairo_convert_data_to_pixbuf: * @src: a pointer to pixel data in cairo format * @dst: a pointer to pixel data in pixbuf format * @width: image width * @height: image height * @rowstride: data rowstride * * Converts the pixel data stored in @src in CAIRO_FORMAT_ARGB32 cairoformat * to GDK_COLORSPACE_RGB pixbuf format and move them * to @dst. If @src == @dst, pixel are converted in place. **/ voidgo_cairo_convert_data_to_pixbuf (unsigned char *dst, unsigned char const*src, int width, int height, int rowstride){ int i,j; unsigned int t; unsigned char a, b, c; g_return_if_fail (dst != NULL); #define MULT(d,c,a,t) G_STMT_START { t = (a)? c * 255 / a: 0; d = t;}G_STMT_END if (src == dst || src == NULL) { for (i = 0; i < height; i++) { for (j = 0; j < width; j++) {#if G_BYTE_ORDER == G_LITTLE_ENDIAN MULT(a, dst[2], dst[3], t); MULT(b, dst[1], dst[3], t); MULT(c, dst[0], dst[3], t); dst[0] = a; dst[1] = b; dst[2] = c;#else MULT(a, dst[1], dst[0], t); MULT(b, dst[2], dst[0], t); MULT(c, dst[3], dst[0], t); dst[3] = dst[0]; dst[0] = a; dst[1] = b; dst[2] = c;#endif dst += 4; } dst += rowstride - width * 4; } } else { for (i = 0; i < height; i++) { for (j = 0; j < width; j++) {#if G_BYTE_ORDER == G_LITTLE_ENDIAN MULT(dst[0], src[2], src[3], t); MULT(dst[1], src[1], src[3], t); MULT(dst[2], src[0], src[3], t); dst[3] = src[3];#else MULT(dst[0], src[1], src[0], t); MULT(dst[1], src[2], src[0], t); MULT(dst[2], src[3], src[0], t); dst[3] = src[0];#endif src += 4; dst += 4; } src += rowstride - width * 4; dst += rowstride - width * 4; } }#undef MULT} Regards,Jean Le dimanche 22 février 2009 à 16:24 +0200, Dov Grobgeld a écrit :> You can also create a cairo surface of the pixbuf through> cairo_image_surface_create_for_data() like this:> int img_width = gdk_pixbuf_get_width(pixbuf);> > int img_height = gdk_pixbuf_get_height(pixbuf);> > > cairo_surface_t *surface> = cairo_image_surface_create_for_data(gdk_pixbuf_get_pixels(pixbuf),> > CAIRO_FORMAT_RGB24,> img_width,> img_height,> > gdk_pixbuf_get_rowstride(pixbuf));> > but beware that you will need to swap R and B when drawing. See the> cairo-circles.c example at:> > http://giv.sourceforge.net/gtk-image-viewer/gtkimageviewer_tutorial.html> > Regards,> Dov> > 2009/2/22 Tadej Borovšak <tadeboro@xxxxxxxxx>> Hi.> > I missed list the first time (sorry Roei for spamming you).> > > ---------- Forwarded message ----------> From: Tadej Borovšak <tadeboro@xxxxxxxxx>> Date: 2009/2/22> Subject: Re: cairo_surface_t to pixbuf> To: Roei Azachi <roei@xxxxxxxxxxxxxxxx>> > > 2009/2/22 Roei Azachi <roei@xxxxxxxxxxxxxxxx>:> > Hi,> > I was wondering if there is a way of converting> cairo_surface_t to pixbuf> > currently I am doing:> > cairo_surface_write_to_png(oimg2, "tmp.png");> > pixbuf = gdk_pixbuf_new_from_file("tmp.png", &g_err);> > I'm sure there is a way, but I don't know how...> > Thanks,> > Roei> > _______________________________________________> > gtk-list mailing list> > gtk-list@xxxxxxxxx> > http://mail.gnome.org/mailman/listinfo/gtk-list> >> > > Hi.> > I only converted cairo's image surfaces to PPM images. I did> this by> obtaining surface's width, height, rowstride and format, then> manually> copied pixel values from surface to PPM.> > Simple function for converting surface to pixbuf would look> something like this:> > ------- CODE --------> GdkPixbuf *> convert( cairo_surface_t *surface )> {> GdkPixbuf *pixbuf;> gint width = cairo_image_surface_get_width( surface );> gint height = cairo_image_surface_get_height( surface );> gint stride = cairo_image_surface_get_stride( surface );> cairo_format_t format => cairo_image_surface_get_format( surface );> guchar *data = cairo_image_surface_get_data( surface );> gint row, col;> > if( format == CAIRO_FORMAT_ARGB32 )> {> guchar *pixels;> gint pix_stride;> > /* Temporary pointers for iterating. */> guchar *p_dat, *p_pix;> > pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB,> TRUE, 8,> width, height );> pixels = gdk_pixbuf_get_pixels( pixbuf );> pix_stride = gdk_pixbuf_get_rowstride( pixbuf );> > p_dat = data;> p_pix = pixels;> > for( row = 0; row < height; row++ )> {> p_pix = pixels + row * pix_stride;> p_dat = data + row * stride;> > for( col = 0; col < width; col++ )> {> /* Copy now. Cairo image> surfaces use> pre-multiplied> * alpha, this is why we need to> calculate RGB values. */> p_pix[0] = p_dat[1] / p_dat[0] *> 0xff;> p_pix[1] = p_dat[2] / p_dat[0] *> 0xff;> p_pix[2] = p_dat[3] / p_dat[0] *> 0xff;> p_pix[3] = p_dat[0];> > p_pix += 4;> p_dat += 4;> }> }> }> else if( format == CAIRO_FORMAT_RGB24 )> {> guchar *pixels;> gint pix_stride;> > /* Temporary pointers for iterating. */> guchar *p_dat, *p_pix;> > pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB,> FALSE, 8,> width, height );> pixels = gdk_pixbuf_get_pixels( pixbuf );> pix_stride = gdk_pixbuf_get_rowstride( pixbuf );> > p_dat = data;> p_pix = pixels;> > for( row = 0; row < height; row++ )> {> p_pix = pixels + row * pix_stride;> p_dat = data + row * stride;> > for( col = 0; col < width; col++ )> {> p_pix[0] = p_dat[0];> p_pix[1] = p_dat[1];> p_pix[2] = p_dat[2];> > p_pix += 3;> p_dat += 4;> }> }> }> > return( pixbuf );> }> -------- CODE ---------> > Note though that I haven't tested this function, so test it> before> using in real application.> > --> Tadej Borovšak> tadeboro@xxxxxxxxx> tadej.borovsak@xxxxxxxxx> > > > --> Tadej Borovšak> tadeboro@xxxxxxxxx> tadej.borovsak@xxxxxxxxx> > _______________________________________________> gtk-list mailing list> gtk-list@xxxxxxxxx> http://mail.gnome.org/mailman/listinfo/gtk-list> > > > _______________________________________________> gtk-list mailing list> gtk-list@xxxxxxxxx> http://mail.gnome.org/mailman/listinfo/gtk-list _______________________________________________gtk-list mailing listgtk-list@xxxxxxxxxxxxx://mail.gnome.org/mailman/listinfo/gtk-list