How can I convert a Cairo::Surface to Gdk::PixBuf?

To convert a Cairo::Surface to Gdk::Pixbuf, i copied its data pixel by pixel, I created the Cairo::Surface with FORMAT_ARGB32, the pixbuf I created has RGB format and has_alpha set to true.
Using the above I have written the below code, but the image colors are wrong. So what is wrong?

 unsigned char * pixel_of(Cairo::RefPtr<Cairo::ImageSurface> image_surface  , int x , int y){
 int stride = image_surface->get_stride();
 int width = image_surface->get_width();
 int pixel_size = stride / width;

auto ptr = image_surface->get_data();

if(y >= image_surface->get_height() || x >= width){
    return ptr;
} 
    return ptr += y*stride + x*pixel_size; 
}

unsigned char * pixel_of(Glib::RefPtr<Gdk::Pixbuf> pix , int x , int y){
int stride = pix->get_rowstride();
int pixel_size = pix->get_n_channels();

auto ptr = pix->get_pixels();

if(y >= pix->get_height() || x >= pix->get_width()){
    return ptr;
} 

return ptr += y*stride + x*pixel_size;
}

Glib::RefPtr<Gdk::Pixbuf> cairo_surface_to_pixbuf(Cairo::RefPtr<Cairo::ImageSurface> surface){
auto pixbuf = Gdk::Pixbuf::create(Gdk::Colorspace::COLORSPACE_RGB , 1 , 8 , surface->get_width() , surface->get_height());

for(int y=0; y<surface->get_height(); y++){
    for(int x=0; x<surface->get_width();x++){
        unsigned char alpha = pixel_of(surface , x , y )[0];
        pixel_of(pixbuf , x , y)[0] = pixel_of(surface , x , y)[1];
        pixel_of(pixbuf , x , y)[1] = pixel_of(surface , x , y)[2];
        pixel_of(pixbuf , x , y)[2] = pixel_of(surface , x , y)[3];
        pixel_of(pixbuf , x , y)[3] = pixel_of(surface , x , y)[0];
    }
}

return pixbuf;
}

Given that each pixel in the cairo surface corresponds to a pixel in Gdk Pixbuf only the colors and alpha channel order is wrong.

Have you seen the create overload that takes a cairo surface?

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.