【译】重要的图像优化之四:“素人”JPEG下
注明:本人原创翻译,原版为Essential Image Optimization电子书,这里将其拆分为几篇文章发布。另外,文中部分链接可能会因为“网络”原因无法打开。不必着急,我会慢慢将其中一些比较好的内容翻译过来发表,都会在这个“Web图像技术深究”专题中。
目录
- 介绍
- 如何判断我的图像是否需要优化?
- 如何选择正确的图像格式?
- “素人”JPEG
- JPEG的压缩模式
-
什么是WebP?
- WebP的表现如何?
- 谁在生产环境中使用WebP?
- WebP编码如何执行?
- WebP的浏览器支持
- 如何将我的图像转换为WebP?
- 如何在我的操作系统上查看WebP图像?
- 如何提供WebP?
- SVG优化
- 避免使用有损编解码器重复压缩图像
-
减少不必要的图像解码和尺寸调整带来的损耗
- 使用srcset提供HiDPI图像
- 艺术化的响应
- 颜色管理
- 图像拼合技术
- 延迟加载非关键图像
- 避免<code>display: none;</code>的陷阱
- 图像CDN服务对你有意义吗?
- 缓存图像资源
- 预加载关键图像资源
- 图像的网络性能预算
- 最后的建议
- 附注
正文:
JPEG的压缩模式(接上文)
使用JPEG优化编码器
现代化的JPEG编码器会尝试生产出更小更高保真的JPEG文件,同时保持与现有浏览器以及图像处理应用程序的兼容性。它们避免了在运行的系统中引入新的图像格式而带来一系列变化,并给图像优化压缩带来质的变化。这里就有两个这样的编码器,它们是MozJPEG和Guetzli。
简单聊一下:你该使用哪个编码器?
- 一般使用MozJPEG
- 如果你的核心关注点是图像质量,而且不在乎相对较长的编码时间,则使用Guetzli
- 如果你需要更好的可配置性:
- JPEGRecompress (底层使用了MozJPEG)
- JPEGMini:它类似于Guetzli会自动选择最佳质量。但它不如Guetzli技术复杂,而且更快,其目标是在于更适用于网络的最佳质量图像。
- ImageOptim API(这里还有个免费的在线界面):它的颜色处理机制是独一无二的,您可以分开选择颜色质量与整体质量。另外,它可以自动选择色度抽样级别,以便在屏幕截图中保留高分辨率颜色,并避免了在自然照片中平滑色彩的字节浪费。
什么是MozJPEG?
MozJPEG是Mozilla开源提供的现代化的JPEG编码器。它声称要去除JPEG文件的10%左右的体积。使用MozJPEG压缩的JPEG文件可以跨浏览器显示,并且还包括渐进式扫描优化、网格量化(丢弃最少压缩的细节)以及一些优秀的量化预设等功能,可以帮助创建更平滑的高分辨率图像(当然也可以使用ImageMagick,如果你愿意去浏览XML配置)。
MozJPEG不仅被ImageOptim所支持,并且还有一个可靠的可配置imagemin插件。以下是Gulp的简单实现示例:
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
gulp.task('mozjpeg', () =>
gulp.src('src/*.jpg')
.pipe(imagemin([imageminMozjpeg({
quality: 85
})]))
.pipe(gulp.dest('dist'))
);
Modern-Image10.jpg
image.png
MozJPEG:不同质量的文件体积与视觉相似度得分的比较。
我用来自jpeg-archive项目的jpeg-recompress来计算一个源图像的SSIM(结构相似性)分数。SSIM是一种用于测量两个图像之间的相似性的方法,其中的分数就是一个图像对比另一个图像的“完美”相似测量值。
根据我的测量结果,MozJPEG的确是一个很好的选择,它可以保持高视觉质量来压缩网页的图像,同时减少文件的大小。对于中小型图像,我发现MozJPEG(质量= 80-85)可以将文件大小减少30-40%,同时保持可接受的SSIM,在jpeg-turbo库上可以提高了5-6%读取速度。MozJPEG确实要比基线JPEG编码更慢,但这不足以成为你放弃它的理由。
注意:如果您需要一个支持MozjPEG的工具,并包含配置支持,以及一些免费的图像比较实用程序,请查看jpeg-recompress。《Web Performance in Action》的作者Jeremy Wagner提供了一种参考配置,如下:
jpeg-recompress --min 35 --max 70 --strip --method smallfry --loops 16 in.jpg out.jpg
什么是Guetzli?
Guetzli是一个来自谷歌的、有前景的、有些缓慢的感知型的JPEG编码器,它会试图找到一个人眼在视觉上无法区分差异但却体积最小的JPEG文件。Guetzli会执行一系列感知测试,为最终的JPEG提出方案,并对每个方案进行评估。最终在其中选择最高评分的提案作为最终输出。
而为了测量图像之间的差异,Guetzli使用Butteraugli,一种基于人类感知来测量图像差异的模型(下面会介绍)。Guetzli可以考虑到其他JPEG编码器没有的几个视觉属性。例如,人眼所看到的绿光量与蓝色的敏感度之间是存在关系的,因此绿色旁边的蓝色信息的编码就会动态修改的更精准一些。
注意: 图片文件的大小更多取决于你图片的质量,而非使用的编解码器。与通过切换编解码器实现的文件大小节省相比,最低质量和最高质量JPEG之间的文件大小差异要更大的多。因此,设置最低可接受的质量非常重要。避免将您的质量设置得太高,并且不去关注它。
Guetzli 声称当在Butteraugli得到同样的质量评分的情况下,和其他编码器相比可以将数据体积再减小20-30%。使用Guetzli的一个大问题就是,它非常非常慢,目前只适用于静态内容的优化。从它的说明中可以看出,Guetzli需要大量的内存(每百万像素可能需要1分钟+ 200MB的内存)。这里有一个很好的Guetzli实践测试报告。可以看到,Guetzli可以作为你的静态网站构建过程中图片优化的理想拼图,但是在按需执行时就并不合适了。
注意:当您将图像优化作为静态网站的构建过程的一部分时,Guetzli可能更加适用,或者在不需要按照要求执行图像优化的情况时。
像ImageOptim这样的工具,同样支持Guetzli优化(在最新版本中)。
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const imageminGuetzli = require('imagemin-guetzli');
gulp.task('guetzli', () =>
gulp.src('src/*.jpg')
.pipe(imagemin([
imageminGuetzli({
quality: 85
})
]))
.pipe(gulp.dest('dist'))
);
Modern-Image12.jpg
可以看到,为了节省些空间,使用Guetzli编码一张3 x 3MP的图像要花费近七分钟的时间(并且伴随着高CPU使用率)。但是为了存档更高分辨率的照片,我认为付出些代价也是值得的。
Modern-Image13.jpgGuetzli:不同质量的文件体积和视觉相似度得分的比较。
注意:建议在高质量图像(例如未压缩的图像,PNG原图或者100%质量(或无损)的JPEG)上使用Guetzli。虽然它可以在其他质量的图像(例如质量为84或更低的JPEG)上工作,但结果可能较差。
使用Guetzli压缩图像是非常(非常)耗时的,可能会使你的用户转身而去,但是对于较大的图像,这是值得的。我已经可以看到一些使用案例里,Guetzli可以仅仅保留文件大小的40%,同时保持了视觉的保真度。这使它非常适合存档照片。在小到中等大小的图像上,我仍然看到一些地方在应用(在10-15KB的范围内),但是效果并不显著。Guetzli可以在压缩更小的图像上引入更多的液化曲线失真。
您可能还对Eric Portis的这项研究感兴趣,他将Guetzli与Cloudinary的自动压缩功能进行了比较,并从中获得了一些有效的不同数据点。
MozJPEG与Guetzli孰优孰劣?
比较不同的JPEG编码器是很复杂的 —— 它需要比较压缩图像的质量、保真度以及最终文件大小等多项内容。正如图像压缩专家KornelLesiński指出的那样,仅就单方面而非多个角度进行测试比较,很可能会导致一个无效的结论。
那Guetzli和MozJPEG比究竟如何呢?—— Kornel指出:
- Guetzli更适用于更高品质的图像(butteraugli建议最好是
q=90
以上,而MozJPEG更适宜处理q=75
左右的图像) - Guetzli压缩速度要慢得多(都是生成了标准的JPEG,所以解码速度是一样很快的)
- MozJPEG不会自动选择质量设置,但您可以使用外部工具找到最佳质量,例如jpeg-archive
存在多种方法,都可以用于测定压缩图像与原图像的相似度或视觉感知差异度。一些图像质量研究经常会使用像SSIM(结构相似性)这样的方法。然而,Guetzli则是通过优化Butteraugli的方法来实现的。
Butteraugli
Butteraugli是一个来自Google的项目,它可以估算一个人可能会注意到两个图像的视觉降级(即心理视觉相似性)的点,并给出几乎没有区别的两个图像的比对分数。Butteraugli不仅给出一个标量的分数,而且还会计算出图像差异水平的空间图。所以当SSIM专注于计算图像中差异的总和时,Butteraugli则更专注于差异最明显的部分。
Modern-Image14.jpg上图是一个例子:使用Butteraugli找到用户无法注意到视觉差异的最小质量阈值。并且缩小了65%的文件体积。
在真正的实施中,您将会制定一个图像质量的目标,然后运行一些不同的图像优化策略,查看您的Butteraugli分数,然后再找到合适的文件大小与质量级别的最佳平衡点。
Modern-Image15.jpg总而言之,我花费了30分钟来安装Butteraugli到我的Mac上,包括安装Bazel和编译C++的源码。使用它就非常简单了:选择两个图片(一个原图和一个压缩版本)进行比较,它就会给你一个比较分数。
Butteraugli与其他视觉相似度比较算法有什么不同?
[根据一位Guetzli项目成员的这条评论表明,Guetzli在Butteraugli得分最高,但在SSIM和MozJPEG得分也最差。其实,这是符合我自己对图像优化策略的研究的。我会运行Butteraugli和一个Node模块(如img-ssim)比较在使用了Guetzli、MozJPEG的之前和之后,源图像和压缩图像的SSIM分数。
组合编码器?
对于一些较大的图像,我发现将Guetzli与MozJPEG中的无损压缩(jpegtran,而不是cjpeg,避免丢掉了Guetzli完成的工作)结合起来使用,可以将文件大小再减少10~15%(总体55%),并且只有非常小的SSIM评分损失。我只是提醒一下可以在组合使用编码器方面进行一些试验和分析,但是也受到了Ariya Hidayat等业内其他人的好评。
总结来说,MozJPEG是一个初学者友好的网页资源编码器,速度相对较快,可以生成高质量的图像。而Guetzli则是一个资源密集型的编码器,它在较大、更高质量的图像上效果最好,是我建议给中高级用户的一个好选择。