Handling PNG images in C++

This blog post is about png++, one of my favourite C++ libraries.

It’s a wrapper of libpng in C++ that allows to handle PNG images so easily that you’ll never want to use bare libpng again.

All you need to start is to add these two lines in you source files:

#include "png++/png.hpp"
using namespace png;

This is the code to open an existing image:

image img("image.png");

The code to make a new image from scratch differs only in the parameter passed to image’s constructor:

image img(1024,768);

The image class has the get_pixel() and set_pixel() memeber functions to access the individual pixels:

rgb_pixel pixel=img.get_pixel(0,0);
pixel.red=min(255,pixel.red+10); //Increase red color of pixel

The image height and width can be obtained with intuitive get_height() and get_width() memeber functions:

for(int i=0;i<img.get_width();i++)
    for(int j=0;j<img.get_height();j++)
        //Do something

The image can be written to file with the write() memebr function:


Also, this library is header-only. What does it means? That you do not have to compile the library to start playing with it, just exptract the library in the folder where you have your source code, and include the header file “png.hpp”, just that.

Lastly, here is an example code including CMake scripts to show the capabilities of the library. png++.tar.gz

6 Responses to “Handling PNG images in C++”

  1. valentin_gheorghe89@yahoo.com Says:

    hi, thank you for this post … I am really having a tough time trying to compile the two example codes provided in windows 7 VS10. I am quite new to cmake could you please help me in setting this two example working.


    valentin gheorghe

    • fedetft Says:

      Unfortunately I have abandoned windows for a long time, and do not even have a computer with it installed to try compiling that code.
      Anyway, the png++ library depends on libpng, which on Linux is installed by default, but not on windows. It may be the cause of your issues.

  2. Max Nilles Says:

    I went and tested how to do something with every pixel of an image the fastest. The following code tests 4 different Methods, you can test it out or just believe me:
    Method 1 is slightly faster than Method 3
    Method 2 is a shitload faster than Method 1
    Method 4 is slower than Method 2, but faster than 1.
    rgb_pixel *pPtr;
    for(size_t i=0; i<y; ++i) {
    pPtr = &img2[i][0];
    for(size_t j = 0; j<x; ++j) {
    Is the ideal code (it's ~16 times faster). Pointers can be useful.
    Of course, this is mainly noticeable for huge dimensions. It can't hurt to optimize however.

  3. fedetft Says:

    This is nice to know, but I’m wondering if the png++ library gives any guarantee about the memory layout of rgb_pixel objects in memory. Method 2, that is the most attractive from the performance point of view, works from making a pointer from the reference returned by img[i][0], and incrementing that pointer instead of calling img[i][j] repeatedly.
    If all of a sudden the image class changes form row major to column major representation, that code would stop work in strange ways.
    Anyway, thanks for the benchmark code, It’s always interesting to compare different approaches. By the way, on my machine the results are (using g++ -O3 on a laptop with OpenSuse 13.2, Core i7-3630QM)
    iterativ: 0.089429
    Pointer: 0.0162
    Iterativ2: 0.094149
    Pointer2: 0.015439
    so the pointer method is 5.5 times faster than method 1, which is the one I would use to be on the safe side. Maybe there’s some ‘inline’ missing in some of the png++ member functions that could help…

    • Alex Says:

      Internal representation of png::image buffers not going to change “all of a sudden”, trust me :-)

      It’s perfectly fine to grab a pointer to the beginning of a pixels vector and iterate it. Or you could just use vector& row = img[i]; then access pixels with row[j], for example.

      There’s also solid_pixel_buffer added recently that uses a single run of pixels instead of individual vector per row, you might find it useful.

  4. new299 Says:

    I also really like png++, I wrote some instructions on how to use it on MacOS here:


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 32 other followers

%d bloggers like this: