libjpeg-turbo 是一个优秀的,JPEG 解码加速库。但是在程序使用上其实可以更进一步优化。具体为:
# 图片剪裁
JPEG 图片是逐个 MCU(Minimum Coded Unit) 从左到右,从上到下地编码出来的,因此解码可以只解码感兴趣的部分而不用解码整个图片,JPEG 库提供了相对应的操作,`jpeg_skip_scanlines` 可以跳过行,`jpeg_crop_scanline` 可以只解码感兴趣的像素列所在的 MCU ,经过上层封装后能减少 MCU 解码的个数,对于只剪裁很小一部分像素的程序来说会有很大的性能提升。
# 图片缩小
同上,基于 JEPG 的 MCU 特性,每个 MCU 涉及重采样。简单且一般来说,抽样一般是 4:2:0 ,这意味着 16x16 像素大小的 MCU ,Y 通道会被编码成 16x16 ,而 Cb 和 Cr 通道会被编码成 8x8 大小(实际没有这么简单,但先可以这么理解)。在解码时,明显地 Cb 、Cr 通道需要升采样。这时候如果进行图片缩小操作就很浪费 CPU 和内存了,因为 Cb 和 Cr 通道进行了升采样,然后再被缩小,实际上可以不升采样。在 libjepg 里面也提供了这样的接口,只需要在解码时传入 `scale_num` 和 `scale_denom` 就可以控制解码时升降采样大小了。
下面是安利时间,这是我 Golang 上已实现的库,已经实现了主流格式的兼容了,附上 benchmark 。
https://github.com/picone/gojpegturbo
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
https://www.v2ex.com/t/865498
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.