Re: cairo_surface_t to pixbuf



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 gmail com>
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 = "" 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
_______________________________________________
gtk-list mailing list
gtk-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-list



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