首发于codesign

图片压缩之 PNG

PNG(Portable Network Graphics) 是一种大家经常使用的位图格式。

PNG 的特点

  • 位图
  • 支持半透明 (BMP不支持,JPEG不支持,GIF不支持,TIFF支持)
  • 支持无损压缩 (BMP不支持,JPEG支持,GIF不支持,TIFF支持)
  • 不支持动画 (A-PNG没有得到广泛应用,GIF是事实标准)
  • 不支持有损压缩, 确切地说,是没有可调整的质量设置。(JPEG支持,WebP支持)

PNG 的用途

  • 有透明度的图标
  • 有透明度的界面元素,如按钮,背景
  • 对图片尺寸不敏感的一般用途

PNG 的压缩

PNG-8 压缩

虽然 PNG 的自带无损压缩使它比 BMP 和 TIFF 已经「聪明」了很多,但对于网络传播仍然嫌大。PNG-8 是唯一可行的压缩方法。

大家可能立即想到的就是 Photoshop 自带的 PNG-8 压缩。

它的原理是缩减图片的色彩空间,8位就是2的8次方种颜色,也就是256色(或更少)。对于一般的按钮和界面图标,可能只有几种颜色;但对于照片来说,256色肯定完全不够用。为了能显示过渡色,有两种办法来欺骗眼睛。一种是 Diffusion, 有一点像点彩画的做法,用两种相近颜色的来拼凑。它的参数是 Dither,Dither参数越大,混合得越均匀,但文件也会变大。

另外一种就是用图案,看上去不太自然,现在很少用。

Photoshop 自带的 PNG-8 压缩有严重的缺点,就是它的透明只能全透明,不能半透明。虽然这样的格式支持广泛,包括 IE 6 都支持。但也大大限制了 PNG 的使用范围。

透明PNG的压缩

如果不考虑 IE6 的话,又希望在保留透明度同时压缩大小,那么好消息是还可以用第三方工具,在 Mac 上有

ImageAlpha

,网页上有

TinyPNG

。它的原理是让 PNG-8 的 256 色中包含透明色。

可以用的压缩工具:


压缩参数

这些库都有很多参数可以调节。有兴趣的同学可以去亲自尝试一下。我知道你们还是想看现成的结果。

原大 94KB, 无压缩 12KB, pngQuant 压缩后 5KB 几乎无变化, WebP压缩后 3KB 有明显瑕疵。

首先,用 ImageMagick 把图标改小:这里附加了一点锐化和高级的重采样算法,可以保证图片压小了之后清晰。用默认的算法有时图片会糊,但这样会稍微增加计算量。

convert ${input} -resize 68x -unsharp 0x1+0.3 -filter Lanczos ${out}

然后,用 pngquant 把PNG压缩:

pngquant -f --speed 1 --ext opt.png ${input}

如果嫌压缩的机器太闲,最后还可以用PNGOut压缩掉10%左右:

pngout -ks -f6 ${input}

要用 WebP 吗?

WebP 是谷人希 (谷歌!人类的希望!) 推行的自造轮子,它的特点是,支持半透明的有损压缩,像是 PNG 和 JPEG 的杂交品种。技术小白鼠看到 Spec 容易流口水,也容易尝试使用,因为它号称可以比 png 小 45%,比 JPEG 小 30% 什么的。

WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller in size compared to JPEG images at equivalent SSIM index.

但我不建议大规模使用,原因无非:

  • 支持差。Chrome 当然能用,但包括 Photoshop 在内的大多数程序打不开。
  • 压得慢。亲测。人家可能用了高级算法,但对于服务器来说,这点很蛋疼。
  • 逻辑复杂。和理想不同,为了万无一失,你需要两套图片。一套 WebP,一套普通的 PNG 或者 JPEG。这就要压两次,还要存两次,还要加判断的逻辑。
  • 先把手头的 PNG 和 JPEG 压好再说吧!
    不就是为了让图小一点吗,你已经试了所有的办法了吗?压缩参数都优化过了吗?你用 WebP 默认的参数去压,也不会比别人优化过的 PNG 和 JPEG 参数效果好、文件小的。把参数吃透,压到极限,你还觉得文件太大?

其实除了 WebP,还有类似 JPEG 2000 之类的轮子从来就没有推开,我悲观的认为,现有的格式已经足够好,新格式都没有极其显著的优越性,而大家的网速还在提升,带宽成本在下降。于是它们只能算生不逢时吧。

编辑于 2013-08-19 13:51