用于无损压缩一系列屏幕截图的适当图像文件格式
我正在构建一个应用程序,该应用程序在用户在 Windows 桌面上执行“记录”操作的过程中获取大量屏幕截图。
出于显而易见的原因,我想以尽可能有效的方式存储这些数据。
起初我考虑使用 PNG 格式来完成此任务。但我偶然发现了这一点: http://www.olegkikin.com/png_optimizers/
只有最好的算法GUI 图标的图像改善了 3% 到 5%。这是非常令人沮丧的,并表明我需要做得更好,因为仅使用 PNG 不允许我使用以前的帧来提高压缩率。文件大小将随着时间继续线性增长。
我想用一些技巧来解决这个问题:只需将帧按一定数量的组并排保存即可。例如,我可以将 10 个 1280x1024 捕获的内容存储在单个 1280x10240 图像中,然后压缩应该能够利用相邻图像之间的重复。
但问题是用于压缩 PNG 的算法并不是为此设计的。我以 1024 像素间隔任意放置图像,并且一次只能将其中的 10 个组合在一起。根据我在几分钟扫描 PNG 规范后收集到的信息,压缩对单独的扫描线(已过滤)进行压缩,然后组合在一起,因此实际上无法从下面引用来自上方 1024 像素的信息。
所以我找到了 MNG 格式,它扩展了 PNG 以允许动画。这更适合我正在做的事情。
我担心的一件事是有多少支持使用新框架“扩展”图像/动画。我的应用程序中数据生成的本质是新帧会定期添加到列表中。但我确实有一个简单的半解决方案来解决这个问题,即缓存最近生成的一大块数据并增量地生成一个“动画”,例如每 10 帧一次。这将允许我在 RAM 中仅绑定 10 帧的未压缩图像数据,不如立即将其卸载到文件系统,但这并不可怕。整个过程完成后(或者甚至在执行期间在自由线程中使用自由循环),我可以轻松返回并将 10 个组缝合在一起,如果值得这样做的话。
这是我的实际问题,一切都已导致。 MNG 是最适合我的要求的格式吗?这些要求是:1. C/C++ 实现可通过许可许可证使用,2. 24/32 位颜色,4+ 兆像素(有些人运行 30 英寸显示器)分辨率,3. 无损或近乎无损(保留文本清晰度)压缩并提供参考先前帧以帮助压缩的规定。
例如,这是我考虑过的另一个选项:视频编解码器。我想要无损的质量,但我见过 h.264/x264 再现非常清晰的静态图像的示例,并且其性能使我可以以更快的间隔进行捕获。我怀疑我只需要实现这两者并进行自己的基准测试即可充分满足我的好奇心。
I am building an application which takes a great many number of screenshots during the process of "recording" operations performed by the user on the windows desktop.
For obvious reasons I'd like to store this data in as efficient a manner as possible.
At first I thought about using the PNG format to get this done. But I stumbled upon this: http://www.olegkikin.com/png_optimizers/
The best algorithms only managed a 3 to 5 percent improvement on an image of GUI icons. This is highly discouraging and reveals that I'm going to need to do better because just using PNG will not allow me to use previous frames to help the compression ratio. The filesize will continue to grow linearly with time.
I thought about solving this with a bit of a hack: Just save the frames in groups of some number, side by side. For example I could just store the content of 10 1280x1024 captures in a single 1280x10240 image, then the compression should be able to take advantage of repetitions across adjacent images.
But the problem with this is that the algorithms used to compress PNG are not designed for this. I am arbitrarily placing images at 1024 pixel intervals from each other, and only 10 of them can be grouped together at a time. From what I have gathered after a few minutes scanning the PNG spec, the compression operates on individual scanlines (which are filtered) and then chunked together, so there is actually no way that info from 1024 pixels above could be referenced from down below.
So I've found the MNG format which extends PNG to allow animations. This is much more appropriate for what I am doing.
One thing that I am worried about is how much support there is for "extending" an image/animation with new frames. The nature of the data generation in my application is that new frames get added to a list periodically. But I do have a simple semi-solution to this problem, which is to cache a chunk of recently generated data and incrementally produce an "animation", say, every 10 frames. This will allow me to tie up only 10 frames' worth of uncompressed image data in RAM, not as good as offloading it to the filesystem immediately, but it's not terrible. After the entire process is complete (or even using free cycles in a free thread, during execution) I can easily go back and stitch the groups of 10 together, if it's even worth the effort to do it.
Here is my actual question that everything has been leading up to. Is MNG the best format for my requirements? Those reqs are: 1. C/C++ implementation available with a permissive license, 2. 24/32 bit color, 4+ megapixel (some folks run 30 inch monitors) resolution, 3. lossless or near-lossless (retains text clarity) compression with provisions to reference previous frames to aid that compression.
For example, here is another option that I have thought about: video codecs. I'd like to have lossless quality, but I have seen examples of h.264/x264 reproducing remarkably sharp stills, and its performance is such that I can capture at a much faster interval. I suspect that I will just need to implement both of these and do my own benchmarking to adequately satisfy my curiosity.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您可以使用 PNG 压缩实现,则可以轻松优化压缩,而无需使用 MNG 格式,只需将“下一张”图像预处理为与上一张图像的差异即可。如果屏幕截图没有太大变化,这虽然很幼稚,但很有效,并且压缩“几乎为空”的 PNG 会大大减少所需的存储空间。
If you have access to a PNG compression implementation, you could easily optimize the compression without having to use the MNG format by just preprocessing the "next" image as a difference with the previous one. This is naive but effective if the screenshots don't change much, and compression of "almost empty" PNGs will decrease a lot the storage space required.