Saving a simple image buffer to png in C++

22,844

Solution 1

There is a C++ wrapper for libpng called Png++. Check it here or just google it.

They have a real C++ interface with templates and such that uses libpng under the hood. I've found the code I have written quite expressive and high-level.

Example of "generator" which is the heart of the algorithm:

class PngGenerator : public png::generator< png::gray_pixel_1, PngGenerator>
{
  typedef png::generator< png::gray_pixel_1, PngGenerator> base_t;
public:
  typedef std::vector<char> line_t;
  typedef std::vector<line_t> picture_t;

  PngGenerator(const picture_t& iPicture) :
    base_t(iPicture.front().size(), iPicture.size()),
    _picture(iPicture), _row(iPicture.front().size())
  {
  } // PngGenerator

  png::byte* get_next_row(size_t pos)
  {
    const line_t& aLine = _picture[pos];

    for(size_t i(0), max(aLine.size()); i < max; ++i)
      _row[i] = pixel_t(aLine[i] == Png::White_256);
         // Pixel value can be either 0 or 1
         // 0: Black, 1: White

    return row_traits::get_data(_row);
  } // get_next_row

private:
  // To be transformed
  const picture_t& _picture;

  // Into
  typedef png::gray_pixel_1 pixel_t;
  typedef png::packed_pixel_row< pixel_t > row_t;
  typedef png::row_traits< row_t > row_traits;
  row_t _row; // Buffer
}; // class PngGenerator

And usage is like this:

std::ostream& Png::write(std::ostream& out)
{
  PngGenerator aPng(_picture);
  aPng.write(out);
  return out;
}

There were some bits still missing from libpng (interleaving options and such), but frankly I did not use them so it was okay for me.

Solution 2

I'd say libpng is still the easiest way. There's example read -> process -> write png program, it is fairly simple once you strip the error handling (setjmp/longjmp/png_jmpbuf) stuff. It doesn't get simpler than that.

Share:
22,844
henle
Author by

henle

Updated on March 29, 2020

Comments

  • henle
    henle about 4 years

    I'd like to do this in a platform independant way, and I know libpng is a possibility, but I find it hard to figure out how. Does anyone know how to do this in a simple way?

  • henle
    henle about 14 years
    Yes, I saw that. I must say, I was confused, but now that you TELL me that it's simple, it really is ;)
  • Steven Lu
    Steven Lu over 12 years
    I don't find this beautiful. How can this be considered beautiful? Does anybody actually believe that this is a proper way to represent an image? Sorry to use such inflammatory language, but nothing in programming has frustrated me to the point that processing PNG images has. Why make it more complicated than it has to be?