在实现GIF图片缩放的文章中,我们使用了GIF解码器来实现GIF图片的解码,然后修改了SSIV的代码来实现动图的缩放。而APNG也是一种动态图片,是在APNG格式上进行扩展而来的,关于apng的文档参考这个链接,关于PNG的详细资料参考这个链接。

APNG的结构图

普通的png的结构是Signature(校验)开头,然后是IHDR(包含图片信息),然后是各种辅助块,最后是IDAT数据块和IEDN结束块。而APNG的开始和PNG相同,只是在IDAT之前会有acTL块,标识着是APNG图片。APNG还比PNG多了fcTL和fdAT块,其中fcTL的信息是标识着下一帧图片的信息,如宽高,offset等,而fdAT则是数据块,和IDAT类似,却多了一个sequence_number(帧编号)。如果IDAT之前有fcTL那么IDAT的数据则当做第一帧(如上图),否则忽略(如下图)。

块的结构

每一块都是这个结构,4个字节标识数据的长度,4个字节标识块类型,然后是数据(如果数据长度为0则无数据内容),最后是CRC校验。除了PNG签名,其他数据都比较符合这个规则。

然后看一下每个部分的内容。

PNG signature:PNG签名,不是块类型,固定为8字节内容:137 80(P) 78(N) 71(G) 13 10 26 10

IHDR块内容:宽高就表示图片宽高,其他表示图片绘制信息

Width                    4 bytes    宽度
Height                  4 bytes    高度
Bit depth           1 byte    位深
Colour type         1 byte
Compression method  1 byte
Filter method           1 byte
Interlace method    1 byte

acTL块:包含了图片的帧数和循环次数(0表示无限循环)

num_frames     4bytes  帧数
num_plays      4bytes  循环次数

fcTL块:包含了当前帧图片的宽高,offset,延迟,和绘制方式

sequence_number       4bytes    帧编号
width                 4bytes    宽度
height                4bytes    高度
x_offset              4bytes    x偏移
y_offset              4bytes    y偏移
delay_num             2bytes    延迟时间分子
delay_den             2bytes    延迟时间分母(如果未0则视为100,num和len的比就是延迟的秒)
dispose_op            1bytes    绘制下一帧时需要对当前缓冲区的操作
blend_op              1bytes    绘制当前帧时是混合还是直接替换

IDAT块:包含了图片数据。

frame_data            Xbytes    数据,长度由块长度标识决定

fdAT块:包含了帧编号和图片数据

sequence_number       4bytes    帧编号
frame_data            Xbytes    数据,长度由块长度标识决定

IEND块:标识图片的结尾,数据为空。

解析过程:先从数据流中读取信息,把图片各种信息保存下来,相关代码如下

int length, type;
boolean done = false;
while (!err() && !done) {length = readInt(); // 长度type = readInt(); // chunk typeswitch (type) {case APngConstant.IHDR_VALUE:readIHDR();break;case APngConstant.acTL_VALUE:readAcTL();break;case APngConstant.fcTL_VALUE:readFcTL();break;case APngConstant.IEND_VALUE:done = true;break;…………default:skip(length);break;}readCRC();if(!done) done = rawData.position() >= rawData.limit();
}

读取帧信息:获取当前帧信息并组合成图片。先读取PNG签名和第一个IDAT之前的所有除了acTL和fcTL的块信息,如果是IDAT的信息则直接读取;如果是fdAT的信息则需要进行处理,把fdAT块的类型改为IDAT,然后去掉帧编号,加上数据信息,因为改变了块的内容,需要重新进行CRC签名后加上修正后的CRC签名;最后加上IEND块;

CRC签名的方式:先更新TYPE的内容,然后更新数据信息即可。相关代码如下

    public static void updateCRC(int offset, byte[] bytes, int dataLength) {CRC32 crc32 = new CRC32();// update typecrc32.update(bytes, offset, 4);if (dataLength > 0) {// update datacrc32.update(bytes, offset + 4, dataLength);}// 写入修正后的crcwriteInt4ToBytes((int) crc32.getValue(), bytes, offset + 4 + dataLength);}

生成Bitmap:如果是第一帧,可以直接生成图片,如果是其他帧,则需要blend_op来绘制相关区域。先绘制底图,如果blend_op为0(APNG_BLEND_OP_SOURCE)则需要先清除当前区域再绘制;如果是1(APNG_BLEND_OP_OVER)则可以直接绘制该区域。关于底图的处理则是根据dispose_op来操作的,如果是0(APNG_DISPOSE_OP_NONE)则保存当前为底图;如果是1(APNG_DISPOSE_OP_BACKGROUND)则需要清除当前区域后再保存;如果是2(APNG_DISPOSE_OP_PREVIOUS)则不保存(相当于使用上一帧的底图)。

到此实现了整个APNG图片的解析,源码地址。当然还存在一些问题,例如生成bitmap的方式还有待改进。

结合GIF实现缩放的方式,使用同样的方式即可实现APNG图片的缩放。效果图如下

实现APNG图片解码及缩放显示相关推荐

  1. 微信小程序图片等比缩放显示正中间

    这是小程序 image标签的mode ,对图片的缩放做的处理 缩放 scaleToFill 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 缩放 aspectFit 保持纵横比缩放 ...

  2. css 图片居中放大,不同比例图片居中缩放显示的三种方法

    效果 方法一动态给img标签src属性赋值来达到传入不同比例的图片时始终等比例缩放显示,兼容性最好 HTML代码 复制代码 CSS代码 .img-box{ /*限定图片盒子宽高*/ width:500 ...

  3. VC6 + OpenCV1.0实现图片缩放显示

    用vc6新建一个win32控制台程序,代码: /*功能:实现加载jpg图片,并进行缩放显示开发环境: winXP + vc6 + openCV1.0头文件路径:D:\opensource\opencv ...

  4. [css] 如何让大小不同的图片等比缩放不变形显示在固定大小的div里?写个例子

    [css] 如何让大小不同的图片等比缩放不变形显示在固定大小的div里?写个例子 图片等比缩放 img{ object-fit: cover/contain;}div宽高比例固定,跟随屏幕变化而变化, ...

  5. 腾讯云 sdk调用 显示 图片解码失败 解决方案

    参考人脸识别接入常见问题汇总 - 腾讯云开发者社区-腾讯云的第六条 前情提要,接口需要image 的base64编码str,于是我的基本处理办法是 # 初始化用于对比的图片 filename1 = ' ...

  6. PyQt5学习:QLabel 标签控件两种 自适应缩放显示图片 方法比较

    目录 1.测试代码 2.运行结果与代码分析 1.测试代码(注意py文件命名) 1.1Qtdesigner设计的uipy文件 zoomimage_test.py (请注意这个文件一定要命名为zoomim ...

  7. JS控制图片显示的大小(图片等比例缩放)

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

  8. android 图片解码显示流程

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jingxia2008/article/details/32327699 问题来源 android 能 ...

  9. android图片解码显示,android 图片解码显示流程

    问题来源 android 可以在 gallery 里面显示内部存储的图片,支持 jpeg,png,gif,bmp 等,甚至文件类型和图片后缀名不一致,只要是图片文件就能显示,然后 git 只会显示第一 ...

  10. stm32h743单片机嵌入式学习笔记6-压缩图片解码原理

    软件解码: JPEG/JPG 的解码过程可以简单的概述为如下几个部分: 1 .从文件头读出文件的相关信息. JPEG 文件数据分为文件头和图像数据两大部分,其中文件头记录了图像的版本. 长宽.采样因子 ...

最新文章

  1. LeetCode题组:第206题-反转链表
  2. arm 跳转指令跳转范围
  3. 【独家揭秘】如何获得60万开发者信任?
  4. 线程池什么时候调用shutdown方法_ThreadPoolExecutor.shutdown()?
  5. Hadoop_计算框架MapReduce
  6. aix解锁oracle用户,aix用户被锁定的解决办法
  7. mysql trigger 有时 不执行_Mysql 寒假刷题TIPs
  8. timeout 和 deadline
  9. 汇编语言答案-王爽第三版
  10. solr集群solrCloud的搭建
  11. Sentry的安装搭建与使用
  12. Kafka权威指南-学习笔记---第一章
  13. sun认证 java怎么考_Sun认证Java程序员考试技巧分享
  14. psd 直接导入unity
  15. ASP一叶知秋 SaaS将会成为08重点
  16. 阿里云添加管理员用户进行协作
  17. NETSCOUT 1T10G-1000-2PAK网络分析仪套包
  18. 怎样知道别人的WiFi密码?
  19. 全国中学生计算机大赛+试题,全国青少年信息学奥林匹克竞赛(NOI2018)正式开幕(附day1试题)...
  20. 期货黄金交易平台哪个最可靠?如何选择?

热门文章

  1. 中国互联网惊呆老外?微信大数据揭露“无现金”真相
  2. C# 扫描枪扫描条形码与二维码
  3. 项目常用后端代码结构
  4. 多文件自平衡云传输 (六)番外篇 —————— 开开开山怪
  5. mac抹掉磁盘重装系统未能与服务器取得联系_如何用U盘自制Mac笔记本系统重装盘...
  6. 仿百度糯米TP5项目笔记
  7. 深度学习基本算法介绍
  8. 15-构造函数及原型
  9. Python利用re正则表达式抓取豆瓣电影Top250排行榜
  10. 开源护眼工具LightBulb2.3.3汉化说明