摘要
我想尽快写一个.png文件,而不用考虑压缩。也就是说,我不太关心文件大小,但我确实关心写入是否尽快发生。
动机
我正在使用客户端的OpenLayers和后端的python / C ++创建基于Web的地图应用程序。当用户在地图上移动时,应用程序需要能够快速绘制动态内容。我有基于图块(256x256图块)和单图像(“单图块”)版本的工作,但在这两种情况下,后端渲染的最慢部分实际上是将图像保存为png文件(无论是否-disk或in-memory)。例如,我可以在大约200毫秒内生成某个视图的“原始”,“tga”或“tiff”版本,但生成.png版本需要更多的时间,因为.png保存需要几乎整整一秒,而实际保存其他格式的时间是100毫秒或更短(即使“原始”文件是.png文件大小的五倍)。此文件节省的时间也远远超过将结果图像从服务器传输到客户端的时间。 (我的应用程序的一个重要特性是,通常“后端”将与浏览器在同一台机器上运行,因此传输时间可以忽略不计,即使对于大文件也是如此。)
我以为我可以通过调用
使.png快速写入(当使用C ++中的libpng时) png_set_compression_level( png_ptr, 0 );
在调用任何png_write_...
函数之前。但是,虽然该调用确实似乎阻止了libpng压缩文件(生成的文件大小与.raw文件的大小相同),但它并没有使得.png的保存速度明显加快。
请帮忙
我需要对这些图像使用.png,因为我需要它们在基本地图的顶部是透明覆盖,我需要的不仅仅是GIF提供的256种颜色。 OpenLayers只是使用html img标签,所以我的理解是我只能使用有效的img格式。
我认为有一种方法可以通过不进行任何实际压缩来快速编写.png文件(我知道.png是“始终压缩”但我想这可能包括“空压缩”)。看起来你应该能够编写一个简单的固定标题,然后是未压缩的数据,然后是一些固定的页脚。或者也许是相同的想法,但是以逐行的方式。关键是我可以非常快速地在内存中通过这个2.5 MB的原始数据循环进行各种循环,并且可以非常快速地将其转储到各种文件格式,所以看起来我应该能够将它转储到固定的,未压缩的.png格式也很快。
这听起来不错吗?你知道在哪里可以找到代码的例子吗?
答案 0 :(得分:29)
你想要的是一个专门为你的目的的实现;你将不得不编写自己的编码器。它实际上并不太难,规格是免费的。
格式不是太复杂,应该很容易实现编码器
注意:所有值都是无符号的。多字节整数采用“网络字节顺序”(最重要的字节优先)。
格式由chunks组成。 块结构:
您的实施应该只需要幻数和三个chunks:
详细布局:
您的数据将被拆分为65535字节的块 格式很简单:
就是这样
这就是你如何制作一个快速的png文件
答案 1 :(得分:12)
PNG的压缩主要受两个参数的影响:
ZLIB压缩的压缩级别。将其设置为0,png_set_compression_level
实际上等于禁用此压缩。
像素过滤。这可以针对每一行而变化,并且选择通常通过一些启发式来完成,其可以对于大小有效,但是可能是耗时的。请参阅png_set_filter
和png_set_filter_heuristics
如果速度是主要问题(更重要的是,如果禁用ZLIB压缩),您应该选择一个过滤器:PNG_FILTER_NONE
我认为,优化速度还有很多工作要做。与诸如BMP或TGA之类的“原始”格式相比,非压缩PNG仍然具有为每个块计算CRC32的(小)负担,以及用于ZLIB的内部Adler CRC。这就是全部。
(为了记录,我编写了一个完整的纯Java编码器/编码器,它致力于 - 内存和CPU效率:PNGJ)