ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Chrome 小尺寸渲染 JPEG 图片优化:节省内存、加速解码,为何图标却显示不同?

Chrome 小尺寸渲染 JPEG 图片优化:节省内存、加速解码,为何图标却显示不同? 为何微小 JPEG 图片在 Chrome 中显示不同看似是渲染错误的问题实则是 Chrome 中一项巧妙的 JPEG 解码优化。这个图标在我同事电脑上看着更好不久前和同事在他们电脑旁聊天时注意到一个标志在他们电脑上的显示效果和自己电脑上不太一样。在他们电脑上这个标志看起来更细也更接近原始图像。该标志渲染尺寸为 15 像素这里有一张放大后的版本。需注意这不是原始图像事情发生有段时间了所以制作了一张新图像来演示这个问题。左图为 Firefox 显示效果右图为 Chrome 显示效果。如果眯着眼看或者往后退一步会发现 Chrome 显示的那个看起来更粗。有点奇怪但把图像换成 SVG 就解决了这个问题。不过还是很好奇它一开始为什么会这样渲染呢深入研究后发现Chrome 在小尺寸渲染 JPEG 图片时采用了一项巧妙的优化。缩小图像可能会造成资源浪费从 JPEG 图片渲染小尺寸图像的直观方法是先在内存中完全解压缩然后再进行缩小。但这种方法并不总是高效的。想象一下一张 2000×2000 的 JPEG 图片需要显示为 20×20 的尺寸。解压缩后图像占用的内存远远超过最终显示所需的内存。完整图像的位图大约需要 12 MB而最终 20×20 的图像只需要约 1.2 KB。大图中的大部分信息在缩小过程中都丢失了。缩小图像时会丢失哪些信息一个有趣的发现是丢失的信息并非随机的。当图像大幅缩小时消失的信息主要是高频细节。这从直观上很容易理解。想象一棵有很多树叶和粗糙树皮的树这些细微的细节在像素之间变化很快因此属于高频信息。如果把这棵树缩小到很小的尺寸比如 20×10最终会看到顶部是一个绿色的色块代表树叶底部是一根棕色的线条代表树干。缩小后的版本丢弃了精细的细节即高频信息。树木缩小的示意图部分高频信息在一定程度上仍然存在因为这些细节会相互混合。JPEG 如何存储图像数据会尽量避免使用过多专业术语和复杂数学知识来解释但还是会提及一些技术术语若想深入研究这些术语可以作为很好的起点。同时也会跳过 JPEG 完整转换过程中的一些部分因为这里并不需要。在 JPEG 压缩过程中图像会被分割成 8×8 的块然后转换到频域。这个操作称为 离散余弦变换DCT。在一个 8×8 的块中最低频率是纯色。严格来说它并不是真正的频率因为没有任何变化这被称为 直流分量。相反最高频率看起来像棋盘格其中的值变化最大。介于两者之间的代表了频域的其他部分这些被称为 基函数。基函数可以在左上角看到纯色右下角看到棋盘格。因此将一个 8×8 的块转换到频域基本上就是在问这个块中每种模式的含量有多少这些含量被称为 系数。JPEG 压缩在这之后还有几个步骤以高效存储这些系数而有损压缩就发生在这个阶段。但这部分对于讨论的内容并不重要。综合起来以 1/8 比例渲染 JPEG 图片现在假设想将一张图片缩小 8 倍。前面提到的 8×8 块现在可以用缩小后图像中的一个像素来表示。在这个尺寸下图像主要需要低频信息因为就像树木的例子一样高频细节在缩放过程中大多会消失。因此无需解压缩整个 JPEG而是可以跳过高频部分的系数只使用图像粗粒度版本所需的系数。这样就可以在不先完全展开原始图像的情况下得到缩小后的结果。解码后的图像占用空间更小解压缩速度也更快因为跳过了大部分系数。只要缩放比例的分母为 8这种方法就可以扩展到其他比例。这种技术的专业名称是 部分 IDCT 缩放。详见 [jpegclub.org](https://jpegclub.org/djpeg/)如果深入了解会发现这种技术也可用于图像放大逆离散余弦变换将频域转换回图像域。Chrome 的处理方式Chrome 将图像解码和渲染委托给 Skia。对于 JPEG 图片Skia 使用 libjpeg-turbo它实现了部分 IDCT 缩放。这使得当目标尺寸足够小时它可以只解码低频数据。换句话说Chrome/Skia 并不总是先解压缩完整图像然后再进行缩放。它会 [计算分母为 8 的最接近的分数](https://github.com/google/skia/blob/30ad01017a46a31859b580bc907457b0e43907a8/src/codec/SkJpegCodec.cpp#L383)并以该比例解码图像。然后它使用更传统的下采样算法进一步缩放图像直到达到所需尺寸。这就是为什么在机器上图像看起来更粗的原因。因为它渲染的尺寸非常小所以使用部分 IDCT 缩放以 1/8 比例进行解码。因此频域表示中保留下来的唯一数据是直流分量所有的边缘柔化和渐变都未被使用。实际上这里的教训是不应该将 JPEG 用于图标等。该格式及其优化是围绕我们对照片的感知设计的。毕竟从名称就能看出联合 图像 专家组。那么对于这种 JPEG 图片在 Chrome 中的显示差异你有什么看法呢
返回列表