快速写png [英] write png quickly

查看:33
本文介绍了快速写png的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结

我想尽快编写一个 .png 文件,而不用担心压缩.也就是说,我不太关心文件大小,但我确实关心写操作是否尽快发生.

I want to write a .png file as quickly as possible, without a concern for compression. That is, I don't care much about the file size, but I do care that the write happens as quickly as possible.

动机

我正在制作一个基于 Web 的地图应用程序,在客户端使用 OpenLayers,在后端使用 python/C++.当用户在地图上移动时,应用程序需要能够快速绘制动态内容.我有基于瓦片(256x256 瓦片)和基于单个图像(单个瓦片")的版本,但在这两种情况下,后端渲染的最慢部分实际上是将图像保存为 png 文件(无论是-磁盘或内存).例如,我可能能够在大约 200 毫秒内生成某个视图的raw"、tga"或tiff"版本,但生成 .png 版本需要 1.2 秒,因为 .png保存几乎需要一秒钟,而实际保存其他格式的时间为 100 毫秒或更短(即使原始"文件的大小是 .png 文件的五倍).而且这个文件保存时间也大大超过了将结果图像从服务器传输到客户端的时间.(我的应用程序的一个重要属性是,通常后端"将与浏览器在同一台机器上运行,因此传输时间可以忽略不计,即使对于大文件也是如此.)

I am making a web-based map application using OpenLayers on the client side and python/C++ on the back end. The application needs to be able to draw dynamic content quickly as the user moves around the map. I have both tile-based (256x256 tile) and single-image-based ("single tile") versions working, but in both cases the slowest part of the back-end render is actually saving the image as a png file (whether on-disk or in-memory). For instance, I may be able to generate a "raw", "tga", or "tiff" version of a certain view in about 200 ms, but it takes more like 1.2 seconds to generate the .png version just because the .png save takes almost a full second, whereas the time to actually save the other formats is 100 ms or less (and even though the "raw" file is five times the size of the .png file). And this file save time is also significantly more than the time to transfer the resulting image from the server to the client. (One important property of my app is that in general the "back end" will be running on the same machine as the browser, so transfer times are negligible, even for largeish files.)

我认为我可以通过调用使 .png 快速写入(当使用 C++ 中的 libpng 时)

I thought I could make .png writes fast (when using libpng from C++) by calling

    png_set_compression_level( png_ptr, 0 );

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

before calling any png_write_... functions. However, while that call does indeed seem to stop libpng from compressing the file (the resulting file is about the same size as the .raw file), it doesn't make saving the .png noticeably faster.

请帮忙

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

I need to use .png for these image, because I need them to be transparent overlays on top of the base map, and I need more than the 256 colors offered by GIF. OpenLayers is simply using html img tags, so my understanding is that I can only use valid img formats.

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

I would think there would be a way of writing a .png file quickly by not doing any real compression (I understand that .png is "always compressed" but I imagined this could include "null compression"). It seems like you should be able to write like a simple fixed header, followed by the uncompressed data, followed by some fixed footer. Or maybe that same idea but in a line-by-line way. The point being that I can do all sorts of looping through this 2.5 MB of raw data in memory in C++ very quickly, and can dump it to various file formats very quickly, so it seems like I should be able to dump it in a fixed, uncompressed .png format quickly also.

听起来对吗?你知道我在哪里可以找到这样的代码示例吗?

Does that sound right? Do you know where I can find examples of code that does that?

推荐答案

您想要的是专门针对您的目的的实现;您将不得不编写自己的编码器.它实际上并不太难,而且规格是免费的.

what you want is an implementation that is specialized for your purpose; you are going to have to write your own encoder. it's actually not too hard and the specs are free.

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

the format isn't too complex and should be easy to implement an encoder

注意:所有值都是无符号的.多字节整数采用网络字节顺序"(最高有效字节在前).

note: all values are unsigned. Multiple-byte integers are in "network byte order" (most significant byte first).

格式由组成.块结构:

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

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

your implementation should only need the magic number and three chunks:

详细布局:

  • { 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 算法不允许压缩)
  • 过滤方法,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 字节(可预计算)
  • { 137, 80, 78, 71, 13, 10, 26, 10 } (magic number), 8 bytes
  • byte length of IHDR chunk, 4 bytes (value: 13)
  • { 73, 72, 68, 82 } ("IHDR"), 4 bytes
  • width, 4 bytes
  • height, 4 bytes
  • bit depth (per color), 1 byte (8 = 24/32 bit color)
  • color type, 1 byte (2 = RGB)
  • compression method, 1 byte (0 = DEFLATE algo which allows no compression)
  • filter method, 1 byte (0 = no filter)
  • interlace method, 1 byte (0 = no interlace)
  • CRC of IHDR chunk, 4 bytes
  • byte length of IDAT chunk contents, 4 bytes
  • { 73, 68, 65, 84 } ("IDAT"), 4 bytes
  • raw image data with DEFLATE algo wrapping, "byte length of IDAT chunk contents" bytes
  • CRC of IDAT chunk, 4 bytes
  • byte length of IEND chunk, 4 bytes (value: 0)
  • { 73, 69, 78, 68 } ("IEND"), 4 bytes
  • CRC of IEND chunk, 4 bytes (can be precomputed)

DEFLATE 数据编码无压缩

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

your data will be split into chunks of 65535 bytes the format is simple:

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

    就是这样

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

    so that is how you make a fast png file

    这篇关于快速写png的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆