Вопрос

Currently I have a ray-tracing program that produces RGB values in floating point (from 0 to 1) or short values (from 0 to 255). (The relevant code is in ImageTools.cpp and ImageTools.hpp.)

Currently I can produce images by writing PPM, which is horrendously large and bloated.

How can I write a PNG image from one of these arrays?

I prefer not to add a dependency on anything that's not commonly installed on most Linux systems, as I have 0 dependencies so far.

Это было полезно?

Решение

You could use Boost GIL

If you have the raw image data (or can produce it in some way):

unsigned char r[width * height];  // red
unsigned char g[width * height];  // green
unsigned char b[width * height];  // blue

You can write a .png file in this way:

#include <boost/gil/extension/io/png_io.hpp>

boost::gil::rgb8c_planar_view_t view = boost::gil::planar_rgb_view(width, height, r, g, b, width);
boost::gil::png_write_view("out.png", view);

If the image also contains an alpha channel

unsigned char a[width * height];

then

#include <boost/gil/extension/io/png_io.hpp>

boost::gil::rgba8c_planar_view_t view = boost::gil::planar_rgba_view(width, height, r, g, b, a, width);
boost::gil::png_write_view("out.png", view);

Remember to link your program with -lpng

Also take a look at boost gil create image

Другие советы

I would keep the application simple and just continue to write a PPM file, then use an existing converter such as ImageMagick (convert), GraphicsMagick (gm convert), or pnmtopng, which are all open source and free to use, or any of a number of other free or proprietary converters.

You can easily write PPM files in a raw format ("P6") that takes up much less file space and is faster to write and read than the ASCII "P3" format. You don't even need to store the PPM as a file; just pipe it to pnmtopng:

your_application | pnmtopng > out.png

pnmtopng is part of the netpbm library which I assume you are already using. It depends upon libpng and zlib, but you've probably already got those as well.

I'm assuming you don't want to implement the standard yourself and are hence willing to compromise by introducing some dependencies in your project. If so, libpng is commonly installed on most linux systems. http://www.libpng.org/pub/png/libpng.html

You might need to install the devel package to pick up the headers, though this was included on my stock CentOS 6.2 machine.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top