Re: cairo_surface_t to pixbuf

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

 



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

[Index of Archives]     [Touch Screen Library]     [GIMP Users]     [Gnome]     [KDE]     [Yosemite News]     [Steve's Art]

  Powered by Linux