内容概要
理解图片的格式 PNG JPG WebP
如何选择一种图片格式
确定准确质量值
服务端的尺寸大小
减小图像下载大小
大多数流量传输都包含图像。 因此你制作的下载的图片越小就会为用户提供更好的网络体验。 本篇文章提供了让你的图像文件更小以及更加网络友好的指导。
理解图像的格式
Android应用通常使用以下某种或多种文件格式的图片PNGJPG和WebP。 对于每种格式你都可以采取措施缩小图片大小。
PNG
缩小PNG文件的关键是减少构成图像的每行像素中使用的唯一颜色数。通过使用更少的颜色可以提高在其它管道中的压缩能力。
减少独唯一颜色的数量会取得显着效果的原因是PNG压缩效果基于一个水平方向相邻像素颜色变化程度的函数。因此减少PNG图像每行中唯一颜色数量可以减少文件大小。
当决定是否采用这种策略时你应该记住减少唯一颜色的数量实际上等于对图像应用了有损编码。然而编码工具可能不会判断一个细小的偏差导致多糟糕的视觉效果。因此为了保证有效压缩和可接受的图像质量的平衡你应该手动执行此工作
有两个特别有用的方法你可以采取优化索引格式和应用矢量量化。
优化索引格式
任何减少颜色的尝试都应该首先尝试优化颜色以便将图像导出为PNG时可以使用INDEXED格式。 INDEXED颜色模式会选择最佳的256色彩并用索引将所有像素值替换到调色板中。 结果是从1600万色彩减少到仅256色彩等同于从每像素3没有透明度或4具有透明度字节减少到每像素1字节。这种变化向减少文件迈出了重大的一步。
将图像表示为调色图像对于显着改善文件大小有很大帮助因此如果你的大多数图片都可以转换可以好好研究一下。
当然并不是每个图像都可以用256种色彩准确表示。 例如某些图像可能需要257,310,512或912种颜色才能正确显示。 在这种情况下矢量化会可能会有帮助。
矢量化
矢量化VQ也许是对创建索引图像的过程更好地描述。 VQ会对多维数进行舍入处理。 在此过程中你图片中的所有颜色都将根据相似性进行分组。 对于给定的组该组中的所有颜色都将被单个中心点值替换这样可以最大程度地减少该单元格中的颜色错误如果使用Voronoi术语则为“site”。 在图3中绿色点表示输入颜色而红色点是替换输入颜色的中心点。 每个单元格由蓝线界定。
将VQ应用于图像会减少了唯一颜色的数量用视觉质量上“相当接近”的单一颜色替换每组颜色。
此技术也允许你为图像定义唯一颜色的最大数量。 例如图4显示了1670万种颜色每像素24位或bpp的鹦鹉头像旁边是一个只使用163bpp唯一颜色的版本。
你可以明显看到有一些质量的损失; 大多数渐变颜色已经被替换赋予图像带状效果。 因此该图片需要超过16种唯一的色彩。
在管道中设置VQ的步骤可以帮助你对图像中使用的唯一色彩的真实数量有更好地了解并且可以帮助你显著地减小它们。 有很多可用的工具来帮助你实现此技术。
JPG
如果你使用的是JPG图片这里有几种只做很小的改变就可以显著节省文件大小的方法
通过不同的编码方法生成较小的文件不影响质量。
稍微调整质量以得到更好的压缩。
执行这些策略通常可以将文件大小减少高达25。
选择工具时请记住照片导出工具会将不必要的元数据如GPS信息插入到图像中。为了最小化你可以尝试利用现有工具删除这些信息。
WebP
WebP是Android 4.2.1API 17支持的较新的图像格式。 这种格式为网络图像提供了卓越的无损和有损压缩。 使用WebP开发人员可以创建更小更丰富的图像。 WebP无损图像文件平均比PNG小 26% 。 这些图像文件还支持透明度也称为alpha通道成本只有 22% 的字节。
WebP有损图像比同等 SSIM 质量指数下的JPG图像小 25-34% 。 对于可接受有损RGB压缩的场景有损WebP还能支持透明度产生的文件大小通常比PNG小3倍。
有关WebP的详细信息请访问 WebP。
选择一种格式
不同的图像格式适用于不同类型的图像。 JPG和PNG的压缩过程有很大差别产生的效果差别也很大。
决定使用PNG还是JPG通常归结于图像本身的复杂性。图5显示了两个图像由于开发者应用了不同的压缩方案而导致很大的差别。左侧的图像有许多小细节因此使用JPG压缩效率更高。右侧的图像很多区域具有相同颜色使用PNG压缩更有效。
图5 JPG和PNG的适用场景
WebP格式可以支持有损和无损模式是PNG和JPG的理想替代品。唯一要记住的是它只对运行Android 4.2.1API 17及更高版本的设备提供支持。不过幸运的是大多数设备都满足这一要求。
图6提供了一个简单的图示来帮助你决定使用哪种压缩方案。
Figure 6. 如何决定一种压缩方案
确定最佳质量值
有几种技术可以用来实现压缩和图像质量之间的正确权衡。有一种技术使用标量值因此仅适用于JPG和WebP。另一种技术利用了Butteraugli库并可用于所有图像格式。
标量值仅限JPG和WebP
JPG和WebP的强大来自于你可以使用标量值来平衡质量和文件大小。诀窍是找出图像的正确的质量值。太低的质量水平虽然产生文件小但以牺牲图像质量为代价。太高的质量水平会增加文件大小对用户不友好。
最直接的解决方案是选择一些非最大值进行尝试。但是请注意质量值对每个图像的影响不同。例如75的质量在大多数图像上可能看起来很好但在另一些图片上效果可能不好。你应该使用图像的代表性样本对选择的最大值进行测试。此外要确保你是对原始图像执行所有测试而不是压缩版本。
对于每天上传和发送数百万个JPG的大型媒体应用程序来说手动调整每个资源是不切实际的。你可以根据图像类别指定几个不同的质量级别来解决这个问题。例如可以将缩略图的质量设置为35因为较小的图像隐藏了更多的压缩伪影伪影不是很好理解。
Butteraugli
Butteraugli是一个库用于测试图像的视觉误差阈值观察者开始注意到图像质量下降的点。换句话说这个项目试图将压缩图像的失真量化。
Butteraugli允许你定义视觉质量的目标然后运行PNGJPGWebP有损和WebP无损压缩。然后你可以选择文件大小和Butteraugli级别之间效果最佳的图像。图7示出了在视觉失真以至于用户可以感知到之前如何使用Butteraugli来找到最低的JPG质量水平;最终文件大小减少了大约65。
图7.应用Butteraugli技术之前和之后的图像。
Butteraugli允许你基于输出或输入进行处理。也就是说你可以在用户感觉到图像出现明显失真之前找到最低的质量设置或者你可以依次设置图像失真级别去观察对应的质量水平。
服务端的尺寸
在服务器上仅存有一种分辨率的图像的方式是很便利的。当设备访问映像时服务器直接返回给设备该分辨率的图片。
虽然这个解决方案方便了开发者但对用户来说可能很痛苦因为这种方案迫使用户下载比实际需要更多的数据。你应该存储多个大小的图像并根据合适的使用场景提供不同的图像。例如对于缩略图服务应该提供缩略图图像而不是全尺寸的版本这样可以节省很多网络带宽。
这种方法对于下载速度是有利的并且降低了使用有限或按数据量收费用户的成本。图像在设备和主存储器上也会占用更少的空间。在大图像例如4K图像的情况下这种方式还减少了设备在加载图像之前调整大小的时间。
实现此方法需要有一个后端图像服务以提供具有适当缓存的各种分辨率的图像。有几种现有的服务可以帮助你例如App Engine 自带了调整图片大小的功能。