一、主流的图片格式
1、JPEG
目前最常见的图片格式,它诞生于 1992 年,是一个很古老的格式。它只支持有损压缩,其压缩算法可以精确控制压缩比,以图像质量换得存储空间。由于它太过常见,以至于许多移动设备的 CPU 都支持针对它的硬编码与硬解码。
2、PNG
诞生在 1995 年,比 JPEG 晚几年。它本身的设计目的是替代 GIF 格式,所以它与 GIF 有更多相似的地方。PNG 只支持无损压缩,所以它的压缩比是有上限的。相对于 JPEG 和 GIF 来说,它最大的优势在于支持完整的透明通道。
3、GIF
诞生于 1987 年,随着初代互联网流行开来。它有很多缺点,比如通常情况下只支持 256 种颜色、透明通道只有 1 bit、文件压缩比不高。它唯一的优势就是支持多帧动画,凭借这个特性,它得以从 Windows 1.0 时代流行至今,而且仍然大受欢迎。
在上面这些图片格式诞生后,也有不少公司或团体尝试对他们进行改进,或者创造其他更加优秀的图片格式,比如 JPEG 小组的 JPEG 2000、微软的 JPEG-XR、Google 的 WebP、个人开发者发布的 BPG、FLIF 等。它们相对于老牌的那几个图片格式来说有了很大的进步,但出于各种各样的原因,只有少数几个格式能够流行开来。下面三种就是目前实力比较强的新兴格式了:
4、APNG
Mozilla 在 2008 年发布的一种图片格式,旨在替换掉画质低劣的 GIF 动画。它实际上只是相当于 PNG 格式的一个扩展,所以 Mozilla 一直想把它合并到 PNG 标准里面去。然而 PNG 开发组并没有接受 APNG 这个扩展,而是一直在推进它自己的 MNG 动图格式。MNG 格式过于复杂以至于并没有什么系统或浏览器支持,而 APNG 格式由于简单容易实现,目前已经渐渐流行开来。Mozilla 自己的 Firefox 首先支持了 APNG,随后苹果的 Safari 也开始有了支持, Chrome 目前也已经尝试开始支持 ,可以说未来前景很好。
5、WebP
Google 在 2010 年发布的图片格式,希望以更高的压缩比替代 JPEG。它用 VP8 视频帧内编码作为其算法基础,取得了不错的压缩效果。它支持有损和无损压缩、支持完整的透明通道、也支持多帧动画,并且没有版权问题,是一种非常理想的图片格式。借由 Google 在网络世界的影响力,WebP 在几年的时间内已经得到了广泛的应用。
5、BPG
著名程序员 Fabrice Bellard 在去年 (2014年) 发布的一款超高压缩比的图片格式。BPG 使用 HEVC (即 H.265) 帧内编码作为其算法基础,就这点而言,它毋庸置疑是当下最为先进的图片压缩格式。相对于 JP2、JPEG-XR、WebP 来说,同等体积下 BPG 能提供更高的图像质量。另外,得益于它本身基于视频编码算法的特性,它能以非常小的文件体积保存多帧动画。目前阻碍它流行的原因就是 HEVC 的版权问题和它较长的编码解码时间。
二、iOS支持介绍
iOS 底层是用 ImageIO.framework 实现的图片编解码。目前 iOS 原生支持的格式有:JPEG、JPEG2000、PNG、GIF、BMP、ICO、TIFF、PICT,自 iOS 8.0 起,ImageIO 又加入了 APNG、SVG、RAW 格式的支持。在上层,开发者可以直接调用 ImageIO 对上面这些图片格式进行编码和解码。对于动图来说,开发者可以解码动画 GIF 和 APNG、可以编码动画 GIF。
三、静态图片的编码与解码
1、JPEG
目前比较知名的 JPEG 库有以下三个:
1)libjpeg:开发时间最早,使用最广泛的 JPEG 库。由于 JPEG 标准过于复杂和模糊,并没有其他人去实现,所以这个库是 JPEG 的事实标准;
2)libjpeg-turbo:一个致力于提升编解码速度的 JPEG 库。它基于 libjpeg 进行了改造,用 SIMD 指令集 (MMX、SSE2、NEON) 重写了部分代码,官网称相对于 libjpeg 有 2 到 4 倍的性能提升;
3)MozJPEG: 一个致力于提升压缩比的 JPEG 库。它是 Mozilla 在 2014 年发布的基于 libjpeg-turbo 进行改造的库,相对于 libjpeg 有 5% ~ 15% 的压缩比提升,但相应的其编码速度也慢了很多。
除了上面这三个库,苹果自己也开发了一个 AppleJPEG,但并没有开源。其调用了芯片提供的 DSP 硬编码和硬解码的功能。虽然它不如上面这三个库功能完善,但其性能非常高。在我的测试中,其编解码速度通常是 libjpeg-turbo 的 1~2 倍。可惜的是,目前开发者并不能直接访问这个库。
JPEG 编码中 quality 越小,图片体积就越小,质量越也差,编码时间也越短。解码时间并没有很大的差距,可能是其大部分时间消耗在了函数调用、硬件调用上。苹果在自己的相册 Demo 中提供的 quality 的默认值是 0.9,在这个值附近,图像质量和体积、编码解码时间之间都能取得不错的平衡。
2、PNG
相对于 JPEG 来说,PNG 标准更为清晰和简单,因此有很多公司或个人都有自己的 PNG 编码解码实现。但目前使用最广的还是 PNG 官方发布的 libpng 库。iOS 和 Android 底层都是调用这个库实现的 PNG 编解码。
在编解码图形类型(颜色少、细节少)的图片时,PNG 和 JPEG 差距并不大;但是对于照片类型(颜色和细节丰富)的图片来说,PNG 在文件体积、编解码速度上都差 JPEG 不少了。
和 JPEG 不同,PNG 是无损压缩,其并不能提供压缩比的选项,其压缩比是有上限的。目前网上有很多针对 PNG 进行优化的工具和服务,旨在提升 PNG 的压缩比。
pngcrush 是 Xcode 自带的 PNG 压缩工具,相对于设计师用 Photoshop 生成的图片来说,它能取得不错的压缩效果。ImageOptim 则更进一步,对每张图用多种缩算法进行比对,选择压缩比更高的结果,进一步缩小了文件体积。TinyPNG.com 相对于其他工具来说,压缩比高得不像话。它启用了类似 GIF 那样的颜色索引表对 PNG 进行压缩,所以会导致颜色丰富的图片丢失掉一部分细节。如果使用 TinyPNG 的话,最好在压缩完成后让设计师看一下颜色效果是否可以接受。
3、WebP
WebP 标准是 Google 定制的,迄今为止也只有 Google 发布的 libwebp 实现了该的编解码 。 所以这个库也是该格式的事实标准。
4、BPG
BPG 是目前已知最优秀的有损压缩格式了,它能在相同质量下比 JPEG 减少 50% 的体积。
BPG 目前只有作者发布的 libbpg 可用。但作者基于 libbpg 编译出了一个 Javascript 解码器,很大的扩展了可用范围。bpg 可以以无损和有损压缩两种方式进行编码,有损压缩时可以用 quality 参数控制压缩比,可选范围为 0~51,数值越大压缩比越高。通常来说,25 附近是一个不错的选择,BPG 官方工具默认值是 28。
libbpg 目前并没有针对 ARM NEON 做优化,所以其在移动端的性能表现一般。
四、动态图片的编码与解码
动图在网络上非常受欢迎,它近似视频,但通常实现简单、文件体积小,应用范围非常广泛。动图的始祖是 GIF,它自 Windows 1.0 时代就在互联网上流行开来,直到今天仍然难以被其他格式取代。尽管它非常古老,但其所用的原理和今天几种新兴格式几乎一样。
大部分内容是相近的,为了压缩文件体积,通常动图格式都支持一些特殊的方式对相似图片进行裁剪,只保留前后帧不同的部分。
在解码动图时,解码器通常采用所谓“画布模式”进行渲染。想象一下:播放的区域是一张画布,第一帧播放前先把画布清空,然后完整的绘制上第一帧图;播放第二帧时,不再清空画布,而是只把和第一帧不同的区域覆盖到画布上,就像油画的创作那样。
像这样的第一帧就被称为关键帧(即 I 帧,帧内编码帧),而后续的那些通过补偿计算得到的帧被称为预测编码帧(P帧)。一个压缩的比较好的动图内,通常只有少量的关键帧,而其余都是预测编码帧;一个较差的压缩工具制作的动图内,则基本都是关键帧。不同的动图压缩工具通常能得到不同的结果。
1、GIF
GIF 缺陷非常明显:
它通常只支持 256 色索引颜色,这导致它只能通过抖动、差值等方式模拟较多丰富的颜色;
它的 Alpha 通道只有 1 bit,这意味着一个像素只能是完全透明或者完全不透明。
2、APNG
APNG 目前并没有被 PNG 官方所接受,所以 libpng 并不能直接解码 APNG。但由于 APNG 只是基于 PNG 的一个简单扩展,所以在已经支持 PNG 的平台上,可以很轻松的用少量代码实现 APNG 的编解码。
3、WebP
WebP 在 2010 年 发布时并没有支持动图。2012 年 libwebp v0.2 的时候,Google 才开始尝试支持动画,但其实现有很多问题,性能也非常差,以至于 Chrome 团队一直都没有接受。直到 2013 年,libwebp v0.4 时,动画格式才稳定下来才被 Chrome 所接受。
WebP 动图实际上是把多个单帧 WebP 数据简单打包到一个文件内,而并不是由单帧 WebP 扩展而来,以至于动图格式并不能向上兼容静态图。如果要支持动图,首先在编译 libwebp 时需要加上 demux 模块,解码 WebP 时需要先用 WebPDemuxer 尝试拆包,之后再把拆出来的单帧用 WebPDecode 解码。
4、BPG
BPG 本身是基于 HEVC (H.265) 视频编码的,其最开始设计时就考虑到了动图的实现。由于它充分利用了 HEVC 的高压缩比和视频编码的特性,其动图压缩比远超其他格式。
五、动图性能对比
APNG 在文件体积上比 GIF 略有优势,解码时间相差不多。WebP 在体积和解码时间上都具有较大的优势。BPG 在体积上优势最大,但解码时间也最长。这么看来,APNG 和 WebP 都是不错的选择,而 BPG 还有待性能优化。
处于学习目的,本文非原创,出自于《全面掌握移动端主流图片格式的特点、性能、调优等》