Create an RGBA image in C++

Aly picture Aly · Apr 25, 2013 · Viewed 7.8k times · Source

I have a matrix of 640x480x4 values, i.e. 640x480 pixels each with 4 channels (RGBA). I want to create a png file which shows the transparency. I have tried using opencv, but apparently transparency is not supported. What is the quickest and easiest way I can do this, I just need to save a few images?

Answer

zakinster picture zakinster · Apr 25, 2013

As other said, you can't easily write a PNG image file in C++ without using an external library.

libpng is the smallest and most portable solution, it is the official PNG reference library and is used by most of the image library to write and read PNG files. It's a fairly easy to use C library but may not be the best solution for a C++ novice.

Exemple of writing a PNG image with libpng :

FILE *fp = fopen("file.png", "wb");
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
png_infop info_ptr = png_create_info_struct(png_ptr);
png_init_io(png_ptr, fp);

/* write header */
png_set_IHDR(png_ptr, info_ptr, width, height,
    bit_depth, color_type, PNG_INTERLACE_NONE,
    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

png_write_info(png_ptr, info_ptr);

/* write bytes */
png_bytep * row_pointers;
<allocate row_pointers and store each row of your image in it>
png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, NULL);

/* cleanup heap allocation */
for (y=0; y<height; y++) free(row_pointers[y]);
free(row_pointers);

fclose(fp);

As you can see it needs quite some lines to simply initialize the writing context, and I voluntarily removed the error management which is a bit tricky with libpng (use of setjmp as instance) and definitly not suitable for a novice C programmer.

You may take a look at higher level image library such as ImageMagick which has a C++ API called Magick++, here is an example of writing an image in memory to a PNG file :

Magick::Blob blob(data, length); 
Magick::Image image; 
image.size("640x480") 
image.magick("RGBA"); 
image.read(blob);
image.write("file.png");

As you can see, it's much easier with a higher level library.