V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
picone
V2EX  ›  程序员

一种优化的 JPEG 剪裁、缩小图片的解码方法

  •  
  •   picone ·
    picone · 2022-07-11 19:04:40 +08:00 · 1655 次点击
    这是一个创建于 901 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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
    7 条回复    2022-07-12 08:37:02 +08:00
    iamzuoxinyu
        1
    iamzuoxinyu  
       2022-07-11 19:16:53 +08:00
    在前司也用 jpeg-turbo ,原本的 C 接口就很简单易用了,cgo 只要简单包一层就行。
    picone
        2
    picone  
    OP
       2022-07-11 19:23:47 +08:00
    @iamzuoxinyu #1 这取决于需求,如果你的需求是剪裁图片,或者缩放图片,可以考虑一下我说的方法能大大提高性能。
    daimaosix
        3
    daimaosix  
       2022-07-11 22:48:47 +08:00
    大可不必! http://www.thumbor.org
    picone
        4
    picone  
    OP
       2022-07-11 22:53:04 +08:00
    @daimaosix #3 没在一个频道,这里讨论的是业务里常用的剪裁和缩放逻辑怎么做到性能极致
    mikewang
        5
    mikewang  
       2022-07-12 00:22:40 +08:00
    写过 JPEG 编码器,能理解 OP 的想法。
    libjpeg-turbo 是在 libjpeg 基础上在汇编层面上使用 SIMD 指令加速计算,快。
    补充一点:裁剪方面如果是粗略的操作,还可以不解码 MCU 本身,利用 MCU 边长整数倍直接裁,免去 DCT 计算,更快。
    wsph123
        6
    wsph123  
       2022-07-12 06:33:00 +08:00 via iPhone
    这个妙啊
    picone
        7
    picone  
    OP
       2022-07-12 08:37:02 +08:00 via Android
    @mikewang 貌似不行,除非需求的大小都是整数倍。往往要求的剪裁大小都是部分的 MCU ,需要 copy 一次内存然后重新编码。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2637 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 06:39 · PVG 14:39 · LAX 22:39 · JFK 01:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.