一个简单的 PNG 包装器可以工作。有人有片段可以分享吗?

发布于 2025-01-02 22:56:30 字数 961 浏览 0 评论 0原文

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

我想做的只有这两件事。

这将是一个使用 png.h 的极其简单的包装器。嗯,由于 libpng API 极其复杂,所以并不完全简单,但它的概念很简单。

我之前尝试过DevIL。它比 libpng 更容易使用。尽管如此,我还是遇到了问题。此外,DevIL 做得太多了。我只需要精简和平均的基本 PNG 格式支持,而不是其他 20 种格式。

然后我找到此页面。我称赞 Pixel Fairy 和全能的 Google 为我提供了一个银盘上的实现...然后事实证明这把图像搞砸了:在处理后的图像中,每条扫描线中的每四个像素都会丢失。通过阅读源代码,我相当确定这不是应该发生的!它应该将红色归零并将绿色设置为蓝色。那也没有发生。

我也尝试过png++。我遇到的问题是,我无法以兼容加载到 OpenGL 的格式从 PNG 中获取数据,我必须构造另一个缓冲区。它看起来很丑,但在我考虑再给 DevIL 一次机会之前,我肯定会再次尝试 png++。至少因为 png++ 有效。它还具有仅限标题的方面。尽管如此,它确实产生了一堆编译器警告。

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

更新编辑:我找到了这个。那里可能有什么东西。

I'm looking for a way to get a buffer of image data into a PNG file, and a way to get a PNG file into a buffer.

There are just these two things I want to do.

It would be a dead simple wrapper that uses png.h. Well, not exactly dead simple because of the horribly complex libpng API, but the concept of it is.

I tried DevIL before. It is much easier to use than libpng. Still, I have had issues with it. Also, DevIL does too much. I only need lean and mean basic PNG format support, not 20 other formats as well.

Then I find this page. I praised the Pixel Fairy and the Almighty Google for giving me an implementation on a silver platter... Then it turns out this screws up the image: in the processed image every fourth pixel in each scanline goes missing. I am fairly certain from reading the source that this is not meant to happen! It's supposed to zero out red and set green to blue. That didn't happen either.

I have also tried png++. The issue I had with it is that I couldn't get data out of a PNG in a format compatible for loading into OpenGL, I would have to construct another buffer. It just looked ugly, but I will definitely try png++ again before I even think about giving DevIL another shot. Because png++ worked, at least. It's also got the header-only aspect going for it. Still, it did produce a bunch of compiler warnings.

Are there any other contenders? Anybody who has worked with directly using libpng would know how to make what I am asking for: one function that takes a filename and fills a 32-bpp buffer and sets two resolution integers; one function that takes a 32-bpp buffer, two resolution integers, and a filename.

Update-edit: I found this. Might be something there.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

属性 2025-01-09 22:56:30

这个教程似乎有你想要的。

从链接:

 //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);

This tutorial seems to have what you want.

From the link:

 //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);
柠檬心 2025-01-09 22:56:30

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

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

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

I'd add CImg to the list of options. While it is an image library the API is not so high level as most (devil/imagemagick/freeimage/GIL). It is also header only.

The image class has simple width height and data members with public access. Under the hood it uses libpng (if you tell it to with preprocessor directive). The data is cast to whatever type you chose for the templated image object.

CImg<uint8_t>myRGBA("fname.png");
myRGBA._data[0] = 255; //set red value of first pixel
烦人精 2025-01-09 22:56:30

Sean Barrett 为 PNG 图像编写了两个公共域文件 阅读/写作

Sean Barrett has written two public-domain files for PNG image reading/writing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文