一个简单的PNG包装器。有人要分享一个片段吗?

时间:2012-02-06 04:28:44

标签: c++ c image png

我正在寻找一种方法来将图像数据缓冲区转换为PNG文件,以及将PNG文件放入缓冲区的方法。

我想做的就是这两件事。

这将是一个使用png.h的简单包装器。好吧,由于可怕的复杂的libpng API,并不是很简单,但它的概念是。

我之前尝试过DevIL。它比libpng更容易使用。不过,我已经issues了。此外,DevIL 太多。我只需要精简和卑鄙的基本PNG格式支持,而不是其他20种格式。

然后我找到this page。我称赞Pixel Fairy和全能Google为我提供了一个银盘上的实现......然后事实证明这会搞砸图像:在处理过的图像中,每个扫描线中的每四个像素都会丢失。我非常肯定从阅读消息来源说这不是意味着发生!它应该将红色归零并将绿色设置为蓝色。那也没发生。

我也试过png ++。我遇到的问题是我无法以兼容加载到OpenGL的格式从PNG中获取数据,我将不得不构建另一个缓冲区。它看起来很丑陋,但在我考虑给DevIL再拍一次之前,我肯定会再次尝试使用png ++。因为png ++起作用了,至少。它也是唯一的标题方面。尽管如此,它确实产生了许多编译器警告。

还有其他竞争者吗?任何直接使用libpng工作的人都知道如何制作我要求的东西:一个函数,它接受一个文件名并填充32-bpp缓冲区并设置两个分辨率整数;一个函数,它采用32-bpp缓冲区,两个分辨率整数和一个文件名。

更新编辑:我找到了this。可能是那里的东西。

3 个答案:

答案 0 :(得分:2)

tutorial似乎有你想要的东西。

从链接:

 //Here's one of the pointers we've defined in the error handler section:
    //Array of row pointers. One for every row.
    rowPtrs = new png_bytep[imgHeight];

    //Alocate a buffer with enough space.
    //(Don't use the stack, these blocks get big easilly)
    //This pointer was also defined in the error handling section, so we can clean it up on error.
    data = new char[imgWidth * imgHeight * bitdepth * channels / 8];
    //This is the length in bytes, of one row.
    const unsigned int stride = imgWidth * bitdepth * channels / 8;

    //A little for-loop here to set all the row pointers to the starting
    //Adresses for every row in the buffer

    for (size_t i = 0; i < imgHeight; i++) {
        //Set the pointer to the data pointer + i times the row stride.
        //Notice that the row order is reversed with q.
        //This is how at least OpenGL expects it,
        //and how many other image loaders present the data.
        png_uint_32 q = (imgHeight- i - 1) * stride;
        rowPtrs[i] = (png_bytep)data + q;
    }

    //And here it is! The actuall reading of the image!
    //Read the imagedata and write it to the adresses pointed to
    //by rowptrs (in other words: our image databuffer)
    png_read_image(pngPtr, rowPtrs);

答案 1 :(得分:1)

Sean Barrett已为PNG图片reading / writing撰写了两个公共域文件。

答案 2 :(得分:1)

我将CImg添加到选项列表中。虽然它是一个图像库,但API并不像大多数那样高(devil / imagemagick / freeimage / GIL)。它也只是标题。

图像类具有简单的宽度高度和具有公共访问权限的数据成员。在引擎盖下它使用libpng(如果你使用预处理器指令告诉它)。数据将转换为您为模板化图像对象选择的任何类型。

CImg<uint8_t>myRGBA("fname.png");
myRGBA._data[0] = 255; //set red value of first pixel