Fwd: cairo_surface_t to pixbuf



Hi.

I missed list the first time (sorry Roei for spamming you).

---------- Forwarded message ----------
From: Tadej Borovšak <tadeboro gmail com>
Date: 2009/2/22
Subject: Re: cairo_surface_t to pixbuf
To: Roei Azachi <roei zon-networks com>


2009/2/22 Roei Azachi <roei zon-networks com>:
> 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 gnome org
> 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 gmail com
tadej borovsak gmail com



-- 
Tadej Borovšak
tadeboro gmail com
tadej borovsak gmail com


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