【发布时间】:2021-04-02 18:42:42
【问题描述】:
使用 libpng,我正在尝试在 44 兆字节的 PNG 图像中提取文本块(最好验证 PNG 数据没有格式错误(例如缺少 IEND 等)) .我可以用png_read_png 和png_get_text 来做到这一点,但对我来说它花费的时间太长了,0.47 秒,我很确定这是因为图像中有大量的IDAT 块。我怎样才能更快地做到这一点?
我不需要像素,所以我尝试让 libpng 忽略 IDAT 块。
为了让 libpng 忽略 IDAT 块,我试过了:
-
png_read_info(p_png, p_png_information); png_read_image(p_png, nullptr); png_read_end(p_png, p_png_information);跳过IDAT块;崩溃失败。 -
png_set_keep_unknown_chunks使 libpng unknow 关于IDAT和png_set_read_user_chunk_fn(p_png, nullptr, discard_an_unknown_chunk)(discard_an_unknown_chunk是一个函数,它执行return 1;)以丢弃未知块;第一个IDAT块发生了一个奇怪的 CRC 错误并且失败了。
但没能做到。
编辑
在 Windows 10 上作为 Node.js C++ 插件运行,主要用 C++ 编写,具有 i9-9900K CPU @ 3.6 GHz 和千兆字节内存。
使用fs.readFileSync读取SSD上的图像文件,这是一个返回Buffer的Node.js方法,并将其扔给libpng进行处理。
是的,起初,我将长时间的计算归咎于 libpng。现在我看到可能有其他原因导致延迟。 (如果是这样的话,这个问题将是一个糟糕的问题,XY problem。)谢谢你的 cmets。我将再次更彻底地检查我的代码。
编辑 2
由于将 PNG 数据输入提供给 C++ 插件的每一步都保持不变,因此我最终仅使用我的 C 指针魔术和一些 C++ 魔术手动挑选和解码文本块。而且,性能令人印象深刻(处理时间为 0.0020829 秒),几乎是立竿见影的。不知道为什么以及如何。
B:\__A2MSUB\image-processing-utility>npm run test
> image-processing-utility@1.0.0 test B:\__A2MSUB\image-processing-utility
> node tests/test.js
----- “read_png_text_chunks (manual decoding, not using libpng.)” -----
[
{
type: 'tEXt',
keyword: 'date:create',
language_tag: null,
translated_keyword: null,
content: '2020-12-13T22:01:22+09:00',
the_content_is_compressed: false
},
{
type: 'tEXt',
keyword: 'date:modify',
language_tag: null,
translated_keyword: null,
content: '2020-12-13T21:53:58+09:00',
the_content_is_compressed: false
}
]
----- “read_png_text_chunks (manual decoding, not using libpng.)” took 0.013713 seconds.
B:\__A2MSUB\image-processing-utility>
【问题讨论】:
-
你为什么不在分析器下运行它,看看时间花在哪里,而不是猜测? Libpng 是开源的,Vtune 现在是免费的。
-
也许您可以通过 Dropbox、Google Drive 或其他方式共享 PNG? “最好验证 PNG 数据” 到底是什么意思?验证什么?这个大文件的像素尺寸和位深度/颜色类型是多少 - 因为 a)您的磁盘必须读取 44MB,这在 150MB/s 磁盘上可能需要 0.3 秒,b)您可能正在分配 GB 的内存来扩展压缩文件PNG转换成。
-
您还可以澄清一下您的环境 - 在带有 USB 2.0 记忆棒 0.47s 的 Raspberry Pi Zero 上会令人印象深刻。