如何使用c ++从png文件中提取像素?

时间:2011-10-16 23:41:18

标签: c++ png extract pixel

是否有可用的图像库,允许用户从已加载到磁盘上的png文件中提取像素而不对其进行解压缩?

所以我有大小为512x512的100k 8bit图像,其中每个图像的大小为10kb,当采用png格式时。这意味着我只需要1GB的RAM就可以在运行时为我正在编写的程序存储所有图像。

是否可以从像这样的图像中有效地检索像素? 即假设我有一个数组images,其中images[i]引用已加载但未解压缩到RAM的png图像(这是加载png图像时会发生的情况吗?)

然后理想情况下,我想写一些类似

的内容
pixel = images[i].getPixel(x,y);

任何人都知道这是否可行?哪个图书馆?我的假设是假的?

4 个答案:

答案 0 :(得分:2)

我不认为你的要求是实际的。幸运的是,只要您不将所有所有内存同时保留在,这也是不必要的。

您是否可以根据需要简单地(加载和)解压缩,然后在不再需要时立即释放内存?

答案 1 :(得分:2)

我认为如果不解压缩至少图像的前一部分,我就不会得到一个像素。打开文件时,它只会指向磁盘上的压缩数据。当您通过PNG库运行它时,它将被解压缩。

我认为,您最好的选择是阅读和编写PNG的规范库,libpng。它提供了对图像数据和元数据的极佳低级访问,并且可能是最快/最有效的选择。它允许你逐行解压缩数据(也许是块大块的 - 我记不起来了),所以你可以解压缩直到得到你的像素,然后扔掉解压缩的数据并移动到下一个图像。

缺点是它可能不像其他选项那样友好。文档是全面的,以至于单调乏味,IMO,但可能有更简单的教程。另一方面,您可能需要手册中的所有细节来完成您要进行的最小减压。它还有助于解释PNG文件格式,以便您可以更好地管理数据到块级别。

答案 2 :(得分:1)

首先,我不确定我是否理解你没有将图像解压缩到RAM中的要求......

虽然它可能比您正在寻找的库更多,但Cinder库允许您轻松加载图像并使用Surface类迭代像素。

以下是有关如何操作的精彩教程:

http://libcinder.org/docs/v0.8.3/guide___images.html

答案 3 :(得分:1)

我认为你能满足这些要求的最好方法是将所有PNG压缩在内存中(如你所示,大约1GB),并且只想从中获取像素时一次解压缩一个。解压缩的512x512 8位灰度图像的缓冲区大小为256KB。如果图像是RGB,则大小为768KB。如果你还有一个alpha通道,那么大小将是1MB。

您可以找到一个非常轻量级的简单库来解压缩PNG here

如果要隐藏图像在内存中压缩的事实,可以将压缩的PNG数据放在图像类中。如果图像被压缩,此类中的getPixel(x, y)方法将触发解压缩。此类中的类成员可以跟踪已解压缩的图像,当需要解压缩另一个图像时,前一个图像可以删除其解压缩的缓冲区。

对于这样的解决方案,您可能遇到的唯一问题是,如果您迭代100K图像只需要一个像素,系统可以thrash,然后移动到下一个像素。为避免这种情况,您需要从单个图像中获取所需的所有信息,然后转到下一个图像。