PNG 优化技术(一)

原文:Clever PNG Optimization Techniques
作者:Sergey Chikuyonok

作为网页设计师,你可能已经非常熟悉 PNG 格式了,它能够提供功能全面的透明效果。PNG 格式无损、强大,是老 GIF 格式的绝佳替代者。作为Photoshop(或任何其他图像编辑器)的用户,你可能会认为 PNG 的优化选项没有多少,尤其是对真彩色 PNG (在 Photoshop 中为 PNG-24)的选项根本就没有。你们有些人可能甚至认为,这种格式不能再优化了。那么,在本文中我们将终结这个谣传。

本文将从技术角度帮助你优化 PNG 图像。这些技术都来自大量对 PNG 编码器保存数据的方式的研究。我们要先了解一下 PNG 格式的概况,然后再来进一步研究优化技术。

您可能想看看下面的相关文章:

  • Clever JPEG Optimization Techniques
    JPEG优化技术(有人已经翻译了这篇文章,见此

枯燥的一部分

在我们开始钻研图像优化技术之前,我们必须了解一些关于 PNG 格式的技术细节。每个图形格式都有自己的优点和缺点;了解这些有助于您修改原始图像,以取得更好视觉质量和压缩效果。这是专业图像优化之中的一个重要思想。

PNG 作为开源格式已经非常完善,完全可以替代需要专利的 GIF 格式了。他们有一些共同的特征(如索引颜色表),但 PNG 在任何方面都明显优于 GIF。PNG 格式在图像封装和压缩方面引入了一些很酷的功能,但对我们——网页设计者和开发者——其中最重要的是扫描线过滤(scanline filtering)(也称为“三角过滤”(“delta filters”)) 。

扫描线过滤

以下是其工作方式。例如,我们有一个 5 × 5 像素的水平渐变图像。以下是这个图像的示意图(每个数字代表唯一的一个颜色) :

如你所见,所有相同的颜色都是在垂直方向上扩展,而不是水平方向。用 GIF 格式的话,这类图片的压缩率将非常低,原因就是它只压缩水平方向扩展的颜色。让我们看看这个图像可以怎样用扫描线过滤压缩:

每行前面的数字2表示应用过滤器,在这种情况下是“Up”。“Up”过滤器发送信息给 PNG 解码器:“对于当前的像素,提取上方像素的值,并将其添加到当前值。 ”2-5行的值为0,因为每一列的所有像素都是相同的颜色。如果图像比较大,这些数据的压缩率就能更高。例如, 15个值为0的像素可以写为0(15),这就比15个0短得多——这就是压缩方式的共同之处。

我说“可以压缩”,在这个理想试验的情况下,“Sub”过滤器(每一行前为数字1)能提供更好的结果:

“Sub”过滤器给解码器发出信息:“提取左侧像素的值,添加到当前值。”在这个例子中,它的值为1。也许你已经猜到了,这些数据将被非常有效地压缩。

扫描线过滤对我们非常重要,因为我们可以利用它们:特别是,我们可以做一些图像处理,使过滤效果更好。过滤器有5种:None(无过滤),Sub(从当前值减去左侧像素的值),Up(减去上方像素的值),Average(减去左侧和上方像素的平均值)和 Paeth(替代上方、左侧已经左上像素的值,以 Alan Paeth 的名字命名)。

这是旧的 GIF 与应用了这些过滤器的对比:


GIF,2568字节


PNG,372字节

如你所见,GIF 图像整整比 PNG 图像大了7倍

图像类型

另一件重要的事就是要了解 PNG 本质上是图像类型,元数据存储在该文件中。作为 Photoshop 的用户,您应该很熟悉 PNG-8(索引图像)和 PNG-24(真彩色图像)。作为 Fireworks 的用户,您可能知道 PNG-32(带透明的真彩色),真是太乱了,因为Photoshop的 PNG-24 也可以存储带透明的真彩色。嗯,要知道这些都不是官方的,你绝不可能在 PNG 规范中找到这些名词。为方便起见,本文中使用 Photoshop 的 PNG 图像命名规则。

在 PNG 中有5种可用的图像类型:灰度,真彩色,索引颜色,带 Alpha 通道的灰度和带 Alpha 通道的真彩色。还有两个索引颜色的子类型(也是非官方的):位透明度(每个像素可以是完全透明的或完全不透明)和调色板的透明度(每个像素可以半透明)。在第二个类型中,每种颜色与其 alpha 值都存储在调色板中。因此,不透明的红色和50%透明的红色是两个不同的颜色,它们在调色板中占用两个单元。

最糟糕的是,Photoshop 只可以保存其中三种类型:带透明的索引颜色、真彩色和带透明的真彩色。这就是为什么你会发现很多人认为,Adobe Fireworks 是最好的 PNG 优化工具。就个人而言,我并不同意:Fireworks 没有足够的图像处理工具,只不过在保存 PNG 文件时多几个选项而已,当然这是题外话了。

那么诸如 OptiPNGpngcrush 这样的专用软件迟早会派上用场。实质上,这些工具有如下功能:

为图像挑选最佳的图像类型(例如,如果图像中没有太多的颜色,则将真彩色转换为索引颜色) 。
挑选最佳的三角过滤器。
挑选最佳的压缩策略,适当减小颜色深度。

所有这些操作都不会影响到图像质量,却能减小 PNG 图像文件的大小,所以我强烈建议您每次保存 PNG 图像时都使用这些工具。

无聊的碎碎念够了,让我们来变一些魔法!

1.色调分离

这个真彩色图像的优化方法已经广为人知。在 Photoshop 中打开样例图片,点图层面板中的选图标,并选择色调分离:

选择尽可能小数值(通常40就够了)并保存图片:


原来,84KB


分离后,53KB

这里它的原理是:分离仅仅减少了颜色数量,把相似的颜色统一,从而创造了分离区域。这有利于更好地扫描线过滤,及实现更好的压缩。这种方法的缺点是,如果想把 HTML 背景串连在一起的话,色彩交替尤其明显:


原始图像


分离后的图像

2.Dirty Transparency

先看看下面的图片:


75KB


30KB

他们都是用 Photoshop 保存的,而且没有经过任何优化。即使对图中的每个像素进行比较,你也不会发现它们有任何区别。但是为什么前者居然是后者的2.5倍大?

你得用一个特别的 Photoshop 插件才能看到隐藏的细节。插件叫作 Remove Transparency,可以在 PhotoFreebies plugin suite 免费下载到。在进行下一个步骤之前你必须安装它。

在 Photoshop 中打开上面的两张图片,选择 Filer – Photo Wiz -Remove Trasparency。现在,你就可以看到保存在图像中的真实像素信息了:

这是怎么回事?怎么可能从单一图层的 PNG 图片读取原始图像的信息?其实,这很简单。带 alpha 通道的真彩色图像中每个像素都用了4个字节来表示:RGBA。最后一个是 alpha通道,控制该像素透明度:该值为0则完全透明,255则完全不透明。这意味着每一个像素(只要有RGB值)只要 alpha 值为0就可以完全隐藏。但是,这些 RGB 数据仍然存在,而且,它不利于 PNG 编码器进行有效的压缩,同时也使大量数据滞留在文件内。因此,我们必须删除这些隐藏数据(例如填充黑色) ,然后再保存图像。下面是一个比较便捷的方法:

在 Photoshop 中打开上面例子里的第一张图片

Ctrl+单击(在Mac中为 ?+单击)图层面板中的缩略图,建立选区,然后反选:选择 – 反向

切换到快速蒙版模式,按Q键:

那么我们就建立一个半透明图像的蒙版,但我们只需要完全透明的图像。图像 – 调整 – 阈值,并将阈值色阶滑到右端,从而使选区完全透明:

离开快速蒙版模式(按Q键),并用黑色填充选区:

再次反选(选择 – 反向),点击图层面板的 图标,添加蒙版。
就这样,现在以 PNG-24 格式保存图像,然后就会发现75KB的文件变为30KB了。顺便说一下,这些步骤都可以记录为 Photoshop 的动作(下载 Dirty Transparency 动作),以后就可以非常方便地一键操作了。

也许您会认为“Dirty Transparency”是图像编辑器的一个 Bug:既然这些区域既看不见,又占用空间,为什么不在保存前就自动清除它们?那么,这个“bug”也可以轻易地变成一项“功能”。看看下面的图片:


5 537字节


6 449字节

如果从图像中去除透明,您会看到:

尽管第一张图片包含更复杂的图像数据,它却比第二张图片小1KB,这就是上面所说的优化。要解释这一“反常”现象很简单:第一个例子中的图像数据被三角过滤器非常有效地压缩了,而三角过滤器非常适合颜色的平滑过渡(比如渐变) 。

技术控们可以看看 OptiPNG 的输出日志,确认一下第二张图中没有用到任何过滤器。这就是为什么我强烈建议您在使用这些技巧之前阅读枯燥的一部分:如果你不明白你在做什么,就可能导致你的图像得不到有效的压缩。

保持原始图像数据的最终办法是在图像层添加蒙版(我们一会还会讲到):

如你所见,Dirty Transparency 是一个非常强大也非常微妙的技术。在应用前,你必须清楚怎样用,和为什么用。如果你保存的是带透明的 PNG-24 图像,你要做的第一件事就是检查透明区域的图像数据,然后再决定是否清除它们。

3.将透明分离

由于一些半透明像素,你不得不保存一个“重量级”的 PNG-24 文件。如果将图像分成两部分的话,你就能给文件瘦瘦身——一部分是不透明像素,另一部分则为半透明——然后以适当格式保存。比如,你可以以 PNG-24 格式保存半透明像素,而不透明像素则用 PNG-8 甚至 JPEG 格式保存。下面是一个非常方便的方法(也可以记录为动作)。这回,我们请出了俄国的 iPod 老祖宗:


PNG-24,62KB

在图层面板中 Ctrl+单击 或 ?+单击 图像缩略图建立选区:

在通道面板中从选区创建新通道:

取消(Ctrl+D 或 ?+D),选择新建的通道,然后打开阈值(图像 – 调整 – 阈值)。将滑块尽量向右拖动:

这样我们就有了完全不透明像素的蒙版了。现在我们得用这个蒙版来分离原始图层。Ctrl+单击 或 ?+单击 alpha 1通道,转到图层面板,选择原始图层层,打开图层 – 新建 – 通过剪切的图层。这样我们就分离出了不透明和半透明像素。
现在,你需要分别单独保存这两个文件:不透明像素存为 PNG-8,半透明像素存为 PNG-24。你还可以在半透明像素图层使用色调分离技术使文件更小。


PNG-8
128 颜色 + 仿色
17KB


PNG-24
色调分离 35
6KB

对比一下前后结果:


之前
63KB


之后
23KB

这种方法有一个明显的缺点:你得到的是两个而不是一个图像,有时可能就不那么方便使用了(例如,当用在内容管理系统中的产品目录时)。

4.Influence masks

其实,这并不是专门优化 PNG 的技术,而是应用了存储为 Web 和设备所用格式的属性设置:使用通道使颜色深度减低(Color reduction influence mask)和使用通道修改仿色设置(Dithering influence mask)。

不幸的是,这些属性在 Photoshop CS4 中被删除了,所以你只能在 CS4 之前的版本中使用这个工具(我用的是 CS3)。

要知道 influence masks 是怎么个原理,让我们先在 PS 中打开此演示图像,并以以下设置保存为 PNG-8 文件:颜色深度减低:随样性;仿色:无仿色;颜色:256


42KB

我首先注意到的是图中的钟摆非常模糊。它在图中有一块高亮的区域,会吸引过多的注意力。为了使钟摆的颜色过渡更平滑些,我们试着将仿色设为100%:


46KB

钟摆现在看起来好些了,但又有了一个新的问题:图片大小增加了4KB,而不透明背景上又有很多噪点:

我们可以尝试降低仿色值来减少噪点,但图像质量也可能会降低。

基于这些问题,我们试着挑战神奇:以减少色彩数量、减小图像大小,来换取图像质量的提高。Influence masks 就能帮助我们做到。

让我们先从颜色开始。打开通道面板,创建一个新渠道,并将它命名为 color。我们可以确定的是,钟摆部分我们要优先考虑提高其图像质量,因此我们要在相同的位置画一个白色的圆(为了更精确些,你可以暂时打开 RGB 通道) 。

打开存储为 Web 和设备所用格式对话框,并设置如下属性:颜色深度减低:随样性;仿色:无;颜色:128(我们将颜色从256减少到128) 。现在我们必须选择一个 influence masks:点击颜色深度减低列表旁的图标,从下拉菜单中选择 color 通道:现在,我们的图像看起来应该是下面这样:

你可以看到 influence mask 的效果了:钟摆非常完美,但其它部分则变得非常糟糕。设置了 influence mask 后,我们对 Photoshop 说:“你看,伙计,钟摆对于这个图像非常重要,所以要尽可能的保持这一区域的色彩”。Influence mask 的原理与标准的 transparency mask 没什么两样:白色意为图片中最高优先级的区域,黑色的优先级则最低。所有灰色程度适中的区域会成比例的影响到图像。

钟摆现在拥有最高的颜色优先级,所以我们要减低白色的圆的强度,以留出更多颜色给其它区域。关闭存储为 Web 对话框,打开通道面板,选择 color 通道并打开色阶对话框(图像 – 调整 – 色阶:把最大输出色阶设置为50来减低颜色强度:

以同样的设置再次保存为 Web 所用格式:

现在看起来好些了,但在其它区域又有了新问题:

我想你已经明白了 influence masks 的工作原理:你以不同程度的灰色告诉 Photoshop 图像上的重要区域。凭借着无数的尝试和失败,我得到了如下这幅蒙版(你可以直接复制并应用到图像中):

使用通道修改仿色设置大致也相同,除了颜色,不同区域的颜色需要不同的仿色值。更亮的区域需要更多的仿色。这是一个非常有用的功能,因为仿色创建的是不规则的像素模型,会阻碍三角过滤器的压缩。你可以精确地描绘出需要仿色的区域而保持其它区域原封不动,所以就能获得更高的压缩率。

我的仿色通道是这样的:

应用了色彩和仿色通道,其它设置相同(随样性,128色):

128色下看起来也不错,不是吗?再做一些收尾工作:设置为180色,最大仿色设为80%。下面是最终的对比,原始图像,未经优化的:


256色,无仿色,无优化
42KB


180色,优化后
34KB

接下来还请保持关注(RSSTwitter(怨念…——译注)),还会有第二部分的内容,我们将进一步探讨更高层次的技术;我们会谈到灰度模式的图像,使用更少的颜色,降低细节,并讨论进一步优化 PNG 的小技巧,以及 PNG 优化的实例。

相关文章

您可能想看看下面的相关文章:

关于作者

Sergey Chikuyonok 是一名俄罗斯前端网络开发者和作家,对优化工作饱含热情:从图像到 JavaScript 代码的精简和优化。

相关阅读



发表评论

*
*(你的邮箱不会被公开)