Re: Direct manipulation and write to PNG
Andrea Canciani <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <CAN_5=BASaRuTcY5ZYRoVP0omKmYmSCyAZkaq5BO3Brd4c9HFQA@mail.gmail.com> |
On Mon, Jul 9, 2012 at 9:16 PM, Carlos López González <[email protected]> wrote: > Hi! > I'm working on doing direct manipulation of a image surface data and > I'm obtaining weird results when writing to png. > > I want to obtain a image like this: > http://imagebin.org/220100 > > but I get this: > http://imagebin.org/220098 > > To create the image I use the following code: > > ///////////////////////////////////////////////// > #include <cairo.h> > > int main (int argc, char *argv[]) > { > cairo_surface_t *surface; > surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 480, 270); > cairo_surface_flush(surface); > > unsigned char* data; > unsigned char*position; > int w, h, stride; > data=cairo_image_surface_get_data(surface); > w=cairo_image_surface_get_width(surface); > h=cairo_image_surface_get_height(surface); > stride=cairo_image_surface_get_stride(surface); > unsigned char a, r, g, b; > int x, y; > a=255; > r=178; > g=55; > b=55; > for(y=0; y<h; y++) > { > for(x=0; x<w*4; x+=4) > { > position= (unsigned char*)(((char*)data)+y*stride); > position[x]=a; > position[x+1]=r; > position[x+2]=g; > position[x+3]=b; This is wrong as it won't work on little-endian machines. You should access pixels as uint32_t pointers: uint32_t *okposition= (uint32_t*)(((char*)data)+y*stride); okposition[x/4]=(a << 24) | (r << 16) | (g << 8) | b; > } > } > cairo_surface_mark_dirty(surface); > > cairo_surface_write_to_png(surface, "image.png"); > > cairo_surface_destroy(surface); > > return 0; > } > ////////////////////////////////////////////// > > I compiled it with: > > $ gcc -o cairo4 `pkg-config --cflags --libs gtk+-2.0` cairo4.c > > The png image file has the color somehow twisted and modified: > a=56 > r=255 > g=9 > b=88 > > I've re-checked that the written bytes are fine on the memory but I > don't get the right results on the png file. > Can anyone help me to let me know what I'm doing wrong? Or maybe it is > something related to png backend? The issue was simply that you were assuming a different byte order than the one used on your machine. To avoid having these issues, always access whole pixels. Some documentation about pixel formats can be found here: http://cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t As you can see, ARGB32 is a 32-bits format stored native-endian. I hope this helps, but don't hesitate to ask for more clarification if it is not sufficient. Andrea > > Thank you very much!! > -- > Carlos > http://synfig.org > -- > cairo mailing list > [email protected] > http://lists.cairographics.org/mailman/listinfo/cairo -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo