读取图像的一部分而不解析整个文件。使用什么文件格式和库?
在我们当前的项目中,由于需要加载太多图像文件,我们遇到了内存问题。当前系统正在加载纯未压缩的 Microsoft BMP 文件,因此这是明显的问题。
因此,我们正在寻找一种
- 可以快速解析的文件格式(必须在嵌入式 Linux 系统上运行)
- 可以读取图像的某些部分而无需解码整个文件
- 使用无损压缩(请不要使用 8 位颜色表)
- 包括完整的 alpha 通道(不仅仅是 GIF 中的位掩码)
- 在 Linux 和 Windows 上编译和运行
- 可以在商业应用程序中使用(LGPL 很好)
- 可以使用 Photoshop 导出
我的第一个猜测是 PNG,但我不确定是否我可以解析图像的一部分,而无需解码整个文件。您有什么更好的想法或经验可以分享吗?
In our current project, we are running into memory problems since we need to load too many image files. The current system is loading plain uncompressed Microsoft BMP files, so this is the obvious problem.
So, we are looking for a file format that
- is fast to parse (must run on an embedded Linux system)
- can read some part of the image without decoding the whole file
- uses lossless compression (no 8-bit color tables, please)
- includes a full alpha channel (not just a bitmask as in GIF)
- compiles and runs on Linux and Windows
- can be used in a commercial application (LGPL is fine)
- can be exported to using Photoshop
My first guess was PNG, but I am not sure if I can parse part of an image without decoding the whole file. Do you have any better idea or some experiences to share?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
(我的印象是,您面临的是内存压力而不是存储限制 - 如果我错了,请忽略这一点)
压缩会节省存储空间,但我认为这不一定有帮助(甚至可能适得其反)减少内存占用,因为您(或至少操作系统)最终将压缩数据复制到内存中,然后将其解压缩到更多内存。
如果您有相当原始的位图格式,那么计算任何感兴趣的像素的文件偏移量和 fseek() 并获取少量数据是一件简单的事情。将颜色/通道组合在一起的打包格式可能会更好,特别是如果它是直接对您的输出(显示或算法或其他)有用的格式。
因此,一种可能是要么识别现有格式,要么编写一个例程,将图像预处理为可直接用于输出的打包位图格式,并弄清楚如何使其成为 Photoshop 的插件,或者编写一个批量转换器工具插入到嵌入式系统使用的闪存卡或其他存储设备中(您可以将其编码为 imagemagick 的输出驱动程序,以获得该包的输入格式灵活性)。然后,代码的嵌入式端变得极其简单且内存高效,因为它只将实际需要的数据移入 RAM(模 O/S 缓冲读取大小,但这些缓冲区应该在幕后回收)
(My impression is that you are facing ram pressure rather than storage limitations - if I'm wrong about that please disregard this)
Compression will save storage space, but I don't think it's necessarily going to help (and could even be counterproductive) to reducing your ram footprint, since you (or at least the OS) end up copying compressed data into ram and then decompressing it to even more ram.
If you have a fairly raw bitmap format, it's a simple matter to calculate the file offset of any pixels of interest, and fseek() there and get a small amount of data. A packed format that combines the colors/channels together could be even better, especially if it's a format directly useful for your output (display or algorithm or whatever).
So a possibility would be to either identify an existing format that is, or write a routine for pre-processing images into a packed bitmap format directly usable by your output, and figure out how to make this a plug in to photoshop, or write a bulk converter tool plugged into whatever writes the flash cards or other storage devices used by your embedded system (you might look at coding it as an output driver to imagemagick in order to get that packages' input format flexibility). The embedded end of your code then becomes extremely simple and memory efficient since it only moves into ram the data it actually needs (modulo O/S buffered read size, but those buffers should get recycled behind the scenes)
使用 ijg 库 的 JPEG 可以使用。看看这里和此处。
简而言之:
问题是您仍然必须对整个文件进行熵解码,但这只是完整解码管道的一小部分(整个图像的 IDCT 花费的时间最多)。所以你必须传递整个文件,但你并没有真正“解码整个文件”。
由于您关心内存,您可能会松一口气,因为 ijg JPEG 解码器有许多内存管理器,可以在具有不同内存要求的系统上工作。您必须查阅相关文档(它是可分发的一部分,我无法立即在网上找到链接)。
您可以为近乎无损的编码(实际上人眼无法区分)指定低量化参数,或者如果您追求完美的无损编码,则完全跳过量化步骤。
我不确定 JPEG 能否满足的唯一要求是 Alpha 通道。不过,如果您只是将其存储为图像中的另一个颜色通道,JPEG 解码器可能不会关心。
JPEG using the ijg library will work. Have a look here and here.
Briefly:
The catch is you still have to entropy-decode the entire file, but that's only a fraction of the full decoding pipeline (IDCT of the entire image is what takes the most time). So you have to pass over the entire file, but you're not really "decoding the whole file".
Since you're concerned about memory, you'll probably be relieved that the ijg JPEG decoder has a number of memory managers for working on systems with varying memory requirements. You'll have to consult the documentation for that (it's part of the distributable, I couldn't immediately find a link online).
You can specify a low quantization parameter for nearly-lossless encoding (practically indistinguishable to the human eye) or just skip the quantization step altogether if you're after perfectly lossless encoding.
The only requirement I'm not sure that JPEG can satisfy is the alpha channel. Although, if you just store that as another color channel in the image, the JPEG decoder probably won't care.