快速写下png

M K*_*atz 22 png save processing-efficiency openlayers libpng

摘要

我想尽快写一个.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 );
Run Code Online (Sandbox Code Playgroud)

在调用任何png_write_...函数之前.但是,虽然该调用确实似乎阻止了libpng压缩文件(生成的文件大小与.raw文件大小相同),但它并没有使.png的保存速度明显加快.

请帮忙

我需要为这些图像使用.png,因为我需要它们是基本地图顶部的透明叠加层,我需要的不仅仅是GIF提供的256种颜色.OpenLayers只是使用html img标签,所以我的理解是我只能使用有效的img格式.

我认为有一种方法可以通过不进行任何实际压缩来快速编写.png文件(我知道.png是"始终压缩"但我想这可能包括"空压缩").看起来你应该能够编写一个简单的固定标题,然后是未压缩的数据,然后是一些固定的页脚.或者也许是相同的想法,但是以逐行的方式.关键是我可以非常快速地在内存中通过这个2.5 MB的原始数据循环进行各种循环,并且可以非常快速地将其转储到各种文件格式,所以看起来我应该能够将它转储到固定的,未压缩的.png格式也很快.

听起来不错吗?你知道在哪里可以找到代码的例子吗?

Gra*_*vis 30

你想要的是一个专门为你的目的的实现; 你将不得不编写自己的编码器.它实际上并不太难,规格是免费的.

格式不是太复杂,应该很容易实现编码器

注意:所有值都是无符号的.多字节整数采用"网络字节顺序"(最重要的字节优先).


格式由组成.块结构:

  • 块内容的长度,4个字节
  • 块标识符(ASCII),4个字节
  • 块内容,"块内容的长度"字节
  • 标识符的CRC和内容(即不包括长度),4个字节

你的实现应该只需要幻数和三个:


详细布局:

  • {137,80,78,71,13,10,26,10}(幻数),8个字节
  • IHDR块的字节长度,4个字节(值:13)
  • {73,72,68,82}("IHDR"),4个字节
  • 宽度,4个字节
  • 高度,4个字节
  • 位深度(每种颜色),1字节(8 = 24/32位颜色)
  • 颜色类型,1个字节(2 = RGB)
  • 压缩方法,1个字节(0 = DEFLATE algo,不允许压缩)
  • 过滤方法,1个字节(0 =无过滤器)
  • 隔行扫描方法,1字节(0 =无隔行扫描)
  • IHDR块的CRC,4个字节
  • IDAT块内容的字节长度,4个字节
  • {73,68,65,84}("IDAT"),4个字节
  • DEFLATE算法包装的原始图像数据,"IDAT块内容的字节长度"字节
  • IDAT块的CRC,4个字节
  • IEND块的字节长度,4个字节(值:0)
  • {73,69,78,68}("IEND"),4个字节
  • IEND块的CRC,4个字节(可以预先计算)

DEFLATE数据编码,无压缩

您的数据将被拆分为65535字节的块,格式很简单:

  • 第一个X块
    • 标头,1个字节(值:0)
    • 数据,65535字节
  • 最后一块
    • 标头,1个字节(值:1)
    • 数据,65535字节或更少

而已


这就是你如何制作一个快速的png文件


leo*_*loy 13

PNG的压缩主要受两个参数的影响:

  1. ZLIB压缩的压缩级别.将其设置为0,实际上png_set_compression_level相当于禁用此压缩.

  2. 像素过滤.对于每一行,这可能会有所不同,选择通常是通过一些启发式方法完成的,这可能对大小有效,但可能非常耗时.请参阅png_set_filterpng_set_filter_heuristics如果速度是主要问题(并且,更重要的是,如果禁用ZLIB压缩),您应该选择单个过滤器:PNG_FILTER_NONE

我认为,优化速度还有很多工作要做.与诸如BMP或TGA之类的"原始"格式相比,非压缩PNG仍然具有为每个块计算CRC32的(小)负担,以及用于ZLIB的内部Adler CRC.这就是全部.

(为了记录,我编写了一个完整的纯Java编码器/编码器,它致力于 - 内存和CPU效率:PNGJ)