引言

不知道每天上下班的你坐在地铁公交上会刷哪些app呢?也许正为周末和朋友去哪里聚会而挑选餐厅;也许刷着朋友圈看看朋友们有哪些新动态;也许在Ins上浏览着大V博主们晒的美照。地铁中信号不理想的状况时有发生,此时的你可能需要等待屏幕中间的小圆圈一直转好一会儿,图片才会加载完毕。解决这样的痛点当然有两种方案:依赖电信运营商铺设更多的基站以及热点来扩大数据信号的覆盖面及提升信号强度;或者,依靠腾讯云不断增强的图片处理能力在给定带宽的条件下提升图片的下载体验。

在今天星罗棋布的互联网环境下,每秒都有几亿张图片飞舞其间,其中万象优图支撑了海量的请求。主流的图片格式包括jpeg/gif/png/webp。每一种格式都有着不同的特点,存在着特性各异的优化空间。我们将分小节为大家拆解其中的奥妙。

GIF

GIF图片与其它格式图片最大的区别在于将时间轴这个维度代入到原本静态的视觉表示中,使得信息的表达更加鲜活。不过随着网络带宽及视频技术的突飞猛进,GIF眼看就快要退出历史舞台了。然而,历史往往就是这么吊诡,近年来的表情包文化使得GIF图片起死回生,焕发出了新的活力。总结一下GIF图在表情包应用中的特点包括:内容简单、画质要求不高、兼容性强(不需要特定解码器即可在各通用平台上展示)。基于此,我们可以为GIF图片进行全方位的“瘦身”:

1. 利用前后帧的相关性进行优化

gif动画通常分为视频截图和人工制作两类。人工制作类的gif有着背景相对固定,色彩数较少以及纯色区域较多的特性。如下图所示:

图1 前后帧相关性样例gif图

这张gif图通过我们的优化可以在存储时实际只存储为:

图2 样例图分解示意图

然后在图像实际展示时再还原为:

图3 样例图分解还原示意图

经过合并帧的处理,万象优图中GIF可以在完全没有任何损失的前提下降低gif图片的存储量。实际效果如下图所示:

图4 帧间优化效果示意图

某些极端情况下,如果前后两帧内容完全相同,此时帧间优化的效率最大,如下图所示一幅5帧的gif图,前3帧内容相同的时候只通过帧合并手段就可以节省约一半的图片大小:

图5 帧合并效果图

2. 利用画质不敏感的特性做降色处理

gif图是一种索引色图像。也就是说,每一张gif图中所呈现的颜色都由一个预先定义好的调色板所决定,颜色数最多为256。每帧视频截图间的背景可能存在微小的残差。所谓微小残差,本质就是颜色上的细微差别,但其实是非常相近且人眼不易察觉的。那么如果我们把相近的2种颜色合并成为一种颜色的话,我们就获得了进一步压缩图片大小的空间。
万象优图提供了接口供用户根据自身的实际情况灵活降低gif调色板的颜色数,在清晰度和带宽节省上随心搭配,自由权衡。

下图给出了在给定不同颜色数的条件下,压缩后的gif图片与原gif图的大小比例曲线:

图6 降色接口对存储量的作用

同时对于人眼来说,一般程度的降色看起来也毫无违和感,并不觉得图片在视觉上变粗糙很多

图7 降色操作优化效果图

原图颜色数的多少对降色结果有着非常直接的影响,万象优图的降色接口对原图颜色丰富的gif比颜色单一的gif作用效果更为明显。用户可考虑自身情况灵活使用,达到最佳效果。

Jpeg与Webp

jpeg格式的图片由于其支持有损、采用直接色等特色使得其非常适合于存储照片。在现今的网络环境中占据着统治性的市场份额,就如同家用操作系统领域的Windows、个人电脑处理器领域的英特尔等一众行业巨擘的地位一般。对于自然环境类的图片,在人眼视觉几乎不感知的前提下,jpeg格式的图片可以用明显更小的体积提供相同甚至更好的视觉体验,因此获得了广泛的支持。

虽然jpeg图片已经是各图片格式中最适应于网络环境的选择了,但是业界仍然为了追求更好的体验而在不懈地努力。

Mozilla团队开发了Mozjpeg项目使得在不降低图像质量且兼容主流的解码器的情况下,平均降低5%的图片大小。

Google于2010年发布的WebP图片格式在相同质量下可以比jpeg图片节省约25%的文件大小,该图片格式也加入了万象优图的图片处理武器库中。

Webp图片格式虽然是一把节省流量的利器,但是多数情况下需要用户集成特定的Webp解码器到自己的应用中才能正常展示,这意味着额外的开发维护成本。那么是否存在无需额外开发量就能进一步节省流量的方法呢?

下面敲黑板,划重点的时间到了。最近开源的新型jpeg编码器Guetzli基于新型的视觉感知模型Butteraugli来有选择的丢弃图片细节信息以达到同样视觉效果下更高的压缩率。经过实际测试发现,在相同质量参数条件下Guetzli编码出的jpeg可以节省约30%的图片大小。最近我们将Guetzli进行了优化并且将其集成到腾讯云的图片处理系统中,为业务的成本优化提供了一项新的“技能包”。

图8 Guetzli优化效果图

接下来本文将简要描述Guetzli的原理以及万象优图在这方面所做的优化。

Guetzli的压缩标准基于Butteraugli的评价体系,其采用三个传统方法没有考虑的原则:

a. 色彩间的相互掩蔽。人眼对强黄色光附近蓝色光强度变化是不敏感的,因此黄光区域附近的蓝色区域可以用更少的bit进行编码。

b. 人眼对蓝光有着较低的空间分辨率,视网膜中用于分辨高清细节的区域没有蓝色光的受体,故高频区域的蓝色光部分可以用更粗的粒度编码。

c. 纹理掩蔽效应。将图像中的高频噪声区域分辨出来进行粗粒度的编码。

总体来看,Guetzli的处理优化可以概括为如下三个部分

图9 Guetzli优化立足点

  • 通过标准libjpeg库编码出的Jpeg所使用的是一套固定不变的,与图像独立的量化表。因此,在Jpeg量化表优化领域内的论文将优化思路集中于两个套路上:给定图像的目标像素比特率,使得图像的失真最小化(以优化视觉体验为目标);或者给定图像的失真容忍度,使得图像的像素比特率最小(以减小带宽为目标)。Guetzli采用的是第二种思路。Guetzli对于失真的评价体系来源于Butteraugli,而对于如何获取到比特率最小的图像结果所采用的方法是按照一定的规则多次迭代尝试。
  • “选择性丢弃高频信息”和“视觉体验优化”本质上是同一套原理下的不同表达而已。核心原理是基于游程编码的特性:邻近区域内连续0值越多,压缩效率越高。首先根据Guetzli自身定义的算法计算出各DCT系数的权重,然后基于权重和与原图的目标失真距离两个因素大量丢弃不重要的接近于0的系数,这部分操作将使得重新编码后的Jpeg图片的大小大幅降低;当丢弃的流程完成后我们再回过头来同样基于这样一套权重和失真评价体系将之前将少量DCT系数重写以微调局部视觉体验,这部分调整又使得编码后的Jpeg图片大小有微微的回升,最终产生出Guetzli所认为的最好的图片返回给我们。这里我们用一个比方也许能更好地让大家理解这一过程。大家都在中学做过用显微镜观察植物细胞壁的实验吧。有一个“粗调”旋钮和一个“微调”旋钮。首先我们会使用粗调方法快速逼近最清晰的视觉效果,当感觉已经接近最佳的时候我们会再用微调的旋钮进行局部微调以达到最好的效果。

通过刚才的描述也许大家也发现了,Guetzli的编码需要不断地做针对输入图片的迭代、调整、尝试以求得最好的效果,这样做的代价便是与传统方法相比消耗了巨大的计算资源,时延从传统Jpeg编码器的10ms级到Guetzli的秒级。于是计算性能的优化势在必行。我们尝试通过减少整个流程的迭代次数、使用并行计算框架等方法目前已能将Guetzli处理的单张处理时延减少一半以上。这个结果固然已经是巨大的进步,但是与传统Jpeg相比仍然有着不小的差距。我们会继续努力提升Guetzli的性能,丰富万象优图的“图片处理军火库”,为用户提供持续增长的价值。

文章来源于腾讯云开发者社区,点击查看原文