Python 如何获取 PNG 格式的图像数据
在学习 PNG 的编码规范,看了 PNG文件结构分析,大概知道图像的数据储存在 IDAT 数据块里,不过不是原始数据,而是对其采用 Zlib 压缩。
于是我在 Python 里 import zlib
,对 PNG 的图像数据进行解压,似乎不能够100%还原图像数据。下面是我的操作过程。
这是我测试的 PNG 图像:
图像大小是2*3像素,像素 RGBA 值如下:
#eb6100ff #22ac38ff #ea68a2ff
#22ac38ff #ea68a2ff #eb6100ff
对应的十六进制数据:
89504e470d0a1a0a0000000d49484452000000030000000208060000009d74661a0000002349444154089963789dc8f05f698dc5ff57198bfe332aadb1f87f624f1603e3cf380600af940c90637dc1550000000049454e44ae426082
根据 PNG 规范定义,IDAT 数据库除去数据块长度码、数据块类型码、CRC码,剩下的就是 IDAT 的内容数据块:089963789dc8f05f698dc5ff57198bfe332aadb1f87f624f1603e3cf380600af940c90
然后在 Python 2.7 用 zlib 对其进行解压:
import zlib
bitData = '089963789dc8f05f698dc5ff57198bfe332aadb1f87f624f1603e3cf380600af940c90'
print zlib.decompress(bitData.decode('hex')).encode('hex')
得到输出:00eb6100ff22ac38ffea68a2ff0122ac38ffc8bc6a0001f95e00
除去扫描行序列00
和01
得到每一个像素的 RGBA 值:
#eb6100ff #22ac38ff #ea68a2ff
#22ac38ff #c8bc6a00 #01f95e00
对比前面像素的 RGBA 值,可见第2行的最后2个像素(c8bc6a00
和01f95e00
)的 RGBA 不是原来的值。不知是哪个环节出了问题,希望 SF 的大神解答下,先谢过了,跪~
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在查看对比这个PNG解压源码与题主的操作流程,发现问题在于少了
undo_filter
这一步。在源码png.py中
可以看出,每行的第一个字节是代表
filter_type
, 不是行号!(因为也不需要!)00
eb6100ff22ac38ffea68a2ff01
22ac38ffc8bc6a0001f95e00这里的00是没有用滤波器,01是指用了减法滤波器
减法滤波器的定义:
c8bc6a00+22ac38ff=ea68a2ff (注意忽略字节进位,即 &ff的作用)