[程序员] 一种优化的 JPEG 剪裁、缩小图片的解码方法

libjpeg-turbo 是一个优秀的,JPEG 解码加速库。但是在程序使用上其实可以更进一步优化。具体为:

# 图片剪裁

JPEG 图片是逐个 MCU(Minimum Coded Unit) 从左到右,从上到下地编码出来的,因此解码可以只解码感兴趣的部分而不用解码整个图片,JPEG 库提供了相对应的操作,`jpeg_skip_scanlines` 可以跳过行,`jpeg_crop_scanline` 可以只解码感兴趣的像素列所在的 MCU ,经过上层封装后能减少 MCU 解码的个数,对于只剪裁很小一部分像素的程序来说会有很大的性能提升。

# 图片缩小

同上,基于 JEPG 的 MCU 特性,每个 MCU 涉及重采样。简单且一般来说,抽样一般是 4:2:0 ,这意味着 16×16 像素大小的 MCU ,Y 通道会被编码成 16×16 ,而 Cb 和 Cr 通道会被编码成 8×8 大小(实际没有这么简单,但先可以这么理解)。在解码时,明显地 Cb 、Cr 通道需要升采样。这时候如果进行图片缩小操作就很浪费 CPU 和内存了,因为 Cb 和 Cr 通道进行了升采样,然后再被缩小,实际上可以不升采样。在 libjepg 里面也提供了这样的接口,只需要在解码时传入 `scale_num` 和 `scale_denom` 就可以控制解码时升降采样大小了。

下面是安利时间,这是我 Golang 上已实现的库,已经实现了主流格式的兼容了,附上 benchmark 。
https://github.com/picone/gojpegturbo