PNG图片中多个数据段(idat)的正确显示问题

lovezypj 2014-05-08 03:22:22
现需要生成一无压缩的png文件。
在网上找到一文:《PNG文件结构分析之二(在手机上生成PNG文件)》(可在google搜到)


我已按这个格式正确生成了png文件
查阅其他资料可知,PNG文件可以有多个IDAT chunk, 但如何组织多个IDAT构成PNG文件则没有详细说明。
作了如下实验,生成的文件用看图软件打开时提示有错。
一个50行50列像素的图,分为连续的两个IDAT存数据,第一个存25行50列(即图像的上半截),另一个IDAT存25行50列(即图像的下半截)。每个IDAT CHUNK的无压缩的LZ77压缩块都以0x78, 0xda, 0x1开头,然后是LEN、NLEN,然后是数据,然后是crc信息。

奇怪的是,2个idat,分别是图像的上半部分和下半部分,如果是一个idat,不管是上半部还是下半部能正常显示,但是合到一起就只显示第一个idat的内容,非常奇怪




看图可知,上面分别是一个png的上半部和下半部,单独显示都ok,合到一起就不行了,第一个idat可以显示,紧接着的第二个就一片空白,不知道多个idat数据要怎么才能正确显示
...全文
7128 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
kilua516 2014-12-21
  • 打赏
  • 举报
回复
不知楼主的问题解决没有,我也遇到同样的问题 我一开始的做法是先将数据分块,得到数据块 A0,A1,A2... 然后按deflate的格式打包,即在每个A数据块前面增加0x01, LEN, ~LEN共5bytes,得到打包后的数据块 B0,B1,B2... 再按zlib的格式进行打包,即在每个B数据块前面增加CMF和FLG,即你提到的0x78, 0xda,得到再次打包后的数据块 C0,C1,C2... 然后按IDAT chunk的格式进行封装,得到的就是与楼主一样的效果 后来仔细研读了一下PNG协议,终于看出问题所在,关键在于PNG协议中有这么一句话: “The compressed datastream is then the concatenation of the contents of all the IDAT chunks” 即是说最后解图的时候是把所有的IDAT中的数据连在一起组成数据流,那么我之前的打包方法把所有的IDAT拼接后就是很多zlib的数据块,感觉不太对劲,所以把方法纠正如下: 第一步一样,按deflate的格式打包,即在每个A数据块前面增加0x01, LEN, ~LEN共5bytes,得到打包后的数据块 B0,B1,B2... 第二步就不同了,这里应该把所有的{B1,B2,B3...}看成一个整体,一个完整的数据流,对这个完整的数据流进行zlib格式打包,得到一个大的数据块 C 然后再按IDAT要求的最大数据长度对C进行分块,放到每一个IDAT中,这样就可以出来正确的图像了 希望对你有帮助
金卯刀 2014-05-15
  • 打赏
  • 举报
回复
为什么不用TPNGObject? 也可以比对你的具体实现和它的差别,看问题出在哪。
lovezypj 2014-05-14
  • 打赏
  • 举报
回复
无解,查不到任何资料
aniugee 2014-05-09
  • 打赏
  • 举报
回复
貌似挺复杂的,建议先去阿发伯的博客上翻翻看 http://blog.csdn.net/maozefa/
lovezypj 2014-05-09
  • 打赏
  • 举报
回复
没人研究过么?w3c文档上也没有找到关于这一块的详细解释
wxj33700 2014-05-08
  • 打赏
  • 举报
回复
帮顶。。。勿沉

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧