使用 mozjpeg 创建高效 JPEG 图片

mozjpeg 项目最近发布了 2.1 版本。其目标是在保持与绝大多数现有解码器兼容性的同时,提高 JPEG 编码相较于现有编码器的效率。

我想解释一下如何使用此软件来减小 JPEG 图片的大小。具体来说,我将介绍 mozjpeg 的 cjpeg 命令行实用程序的使用方法。

构建 mozjpeg

目前没有可用的官方 mozjpeg 二进制文件,因此您需要从源代码构建该项目。您可以 下载最新版本的源代码,并按照 BUILDING.txt 文件 中的说明进行操作。

在 Linux 和 OS X 上构建非常简单。在 Windows 上稍微复杂一些,但仍然相对容易。mozjpeg 项目正在考虑将来提供二进制版本。

构建 mozjpeg 后,您将生成一个名为 cjpeg 的命令行工具。这是 mozjpeg 附带的编码程序。解码器称为 djpeg

输入图像格式

cjpeg 工具能够处理以下输入文件类型:targa、bmp、ppm 和 jpg。

能够将 JPEG 文件作为输入是 mozjpeg 的一项新功能,其他项目的 cjpeg 工具中尚不存在此功能。添加此功能是为了简化重新压缩工作流程。无需将 JPEG 转换为 BMP 或其他格式,然后重新编码,您只需将 JPEG 直接传递给 cjpeg 编码器即可。

如果您想从 cjpeg 不支持的文件类型创建 JPEG,可以查看 ImageMagick 工具。它们包含一个名为 convert 的命令行实用程序,可以将多种类型的图像相互转换。

cjpeg 命令行工具的基本用法

大多数使用 mozjpeg 的 cjpeg 用户都使用其最简单的形式

$ cjpeg -quality 80 foo.bmp > bar.jpg

这将从“foo.bmp”输入文件创建名为“bar.jpg”的 JPEG 文件,质量级别为 80。cjpeg 直接输出生成的 JPEG 文件的内容,因此,如果您想将其写入磁盘(您可能希望这样做),则需要使用“>”将结果输出到文件。

选择质量级别

质量范围从低端的 0 到高端的 100。大多数用户会选择 60 到 90 之间的质量值。您应该使用仍然能够生成您满意质量的图像的最低值,因为较低的值会生成文件较小的图像。

下图显示了一个原始图像以及使用 mozjpeg 的 cjpeg 以五个不同质量级别编码的同一图像。单击图像以放大。

JPEG Quality Comparison

以下是逐个的图像文件

(图片由 Soulmatesphotography 提供,来自维基百科,知识共享署名-相同方式共享 3.0 未移植版本许可证)

进行一些试验。很多人没有做,错过了大幅减少文件大小的机会。他们的想法通常是“80 似乎是一个不错的折衷方案,我听说大多数人都是这么做的,所以我也这么做。”如果您无法区分质量为 77 和 80 的图像,并且您正在使用 80,那么您就错过了在不影响质量的情况下大幅节省文件大小的机会。

渐进式 JPEG 与基线 JPEG

mozjpeg 版本的 cjpeg 默认生成渐进式 JPEG,因为它们的文件大小往往比基线 JPEG 小约 4%。渐进式 JPEG 可以先以较低分辨率显示,然后随着图像下载逐渐提高分辨率直至完整显示。基线 JPEG 则从上到下加载。

基线
jpeg-baseline

渐进式
jpeg-progressive
(图片由 Soulmatesphotography 提供,来自维基百科,知识共享署名-相同方式共享 3.0 未移植版本许可证)

如果您想生成基线 JPEG,可以按如下方式操作

$ cjpeg -baseline -quality 80 foo.bmp > bar.jpg

目标指标

mozjpeg 的 cjpeg 的一个很酷的功能是,您可以针对四个特定的质量指标进行优化:PSNR、PSNR-HVS-M、SSIM 和 MS-SSIM。这些指标是用于计算图像相较于原始图像质量的算法。更科学地说,这通常被称为失真率。

这些算法在定义质量的方式上有所不同,因此针对一个指标进行优化可能会影响另一个指标的性能。请参阅 Mozilla 2014 年 7 月有损压缩图像研究,其中包含许多此类示例。

mozjpeg 默认针对 PSNR-HVS-M 进行优化,因为针对此指标进行优化在所有指标上的表现都相当不错。

如果您或您的组织认为某个特定指标比其他指标更可靠,您可以告知 mozjpeg 的 cjpeg 工具您的偏好,它将针对该指标进行优化。

结论

希望此时您已经了解了足够的信息,可以自信地开始使用 mozjpeg 来优化您的 JPEG 图片。如果您遇到任何问题,请在 mozjpeg 的 GitHub 问题跟踪器 上报告。

关于 Robert Nyman [荣誉编辑]

Mozilla Hacks 的技术布道师和编辑。发表关于 HTML5、JavaScript 和开放网络的演讲和博客文章。Robert 是 HTML5 和开放网络的坚定支持者,自 1999 年以来一直从事 Web 前端开发工作 - 在瑞典和纽约市。他还定期在 http://robertnyman.com 上发表博客文章,并且喜欢旅行和结识新朋友。

更多 Robert Nyman [荣誉编辑] 的文章…

关于 robnymantest

更多 robnymantest 的文章…


27 条评论

  1. Eric Johnson

    到目前为止,您看到的节省的文件大小是多少?

    2014 年 8 月 6 日 上午 08:53

    1. Josh Aas

      所有指标的平均改进约为 5%。根据您要压缩的图像和您关心的指标,您可能会看到更多或更少的改进。请参阅以下研究

      http://people.mozilla.org/~josh/lossy_compressed_image_study_july_2014/

      2014 年 8 月 6 日 上午 11:54

  2. Omega

    “mozjpeg 项目正在考虑将来提供二进制版本。”

    对于像 Mozilla 这样的组织来说,编译二进制文件应该轻而易举。不明白为什么要大费周章。

    2014 年 8 月 6 日 上午 08:55

    1. Adam Tajti

      同意,不过开发者应该具备快速编译和使用该工具的技能。

      2014 年 8 月 6 日 上午 09:23

    2. Robert Nyman [编辑]

      我猜“大费周章”指的是源代码和构建?如果是这样,我喜欢这个说法 :-)
      我们希望以后能够提供二进制版本,这取决于请求数量,但目前还没有提供。

      2014 年 8 月 6 日 下午 13:37

    3. Adam

      可以从 http://goo.gl/oFa7DO 下载 mozjpeg 的二进制版本

      2014 年 8 月 7 日 下午 12:30

  3. Robson

    即使是质量 90 也不够好。压缩产生的噪点太明显了。

    看起来 http://jpegmini.com/ 仍然做得更好。

    让我们看看该项目的未来发展。

    2014 年 8 月 6 日 上午 09:10

    1. Robert Nyman [编辑]

      尝试多种不同的图像,看看您的想法。是的,请关注未来的进展。

      2014 年 8 月 6 日 下午 13:38

  4. Signez

    我认为您打错字了。

    cjpeg -quality 80 foo.jpg > bar.jpg

    应该是

    cjpeg -quality 80 foo.bmp > bar.jpg

    如果我理解正确的话。

    2014 年 8 月 6 日 上午 09:28

    1. Robert Nyman [编辑]

      我们讨论了 BMP 或 JPG 哪个是人们最常用的格式,并且没有将命令和文本匹配到那个地方。已更新,谢谢!

      2014 年 8 月 6 日 上午 11:24

  5. André

    有没有办法在 Windows Server 上运行 mozjpeg?

    2014 年 8 月 6 日 上午 09:31

    1. Josh Aas

      您可以在 Windows 上编译 mozjpeg,然后由您决定如何在工具链中使用该库或 cjpeg。

      2014 年 8 月 6 日 上午 11:56

      1. André

        我在当前的 mozjpeg v2.1 版本中找不到“ALL_BUILD.vcproj”。在哪里可以找到它?

        2014 年 8 月 6 日 下午 23:47

      2. André

        https://github.com/mozilla/mozjpeg/blob/febf3466d4ce1f4309e21dd994fed9205831b9b9/BUILDING.txt#L484

        2014 年 8 月 6 日 下午 23:49

        1. Robert Nyman [编辑]

          据我所知,“ALL_BUILD.vcproj”文件应该在您运行 cmake 命令时生成。

          2014 年 8 月 7 日 上午 03:39

  6. Steve Souders

    我迫不及待地想开始使用 mozjpeg。这篇文章对我的入门帮助很大。您建议对质量级别进行一些试验。我希望将它集成到一个系统中,该系统将压缩数百万张图像。对如此大量的图像进行试验将非常耗时,但是如果我对一个更可行的子集进行试验,则确切的质量级别可能会因图像而异。您对在这种情况下选择质量级别有什么建议吗?谢谢!

    2014 年 8 月 6 日 上午 09:35

    1. Josh Aas

      要测试哪些质量取决于您感兴趣的内容。我建议先在各种质量下测试几个单一图像,以了解什么看起来最合适,然后再对数百万张图像进行运行。

      您还应该查看我们刚刚发布的这项研究

      http://people.mozilla.org/~josh/lossy_compressed_image_study_july_2014/

      其中包含大量关于质量的信息,可以帮助您做出决定。数据是使用此软件收集的

      https://github.com/bdaehlie/web_image_formats

      它支持图像并行处理。对于我链接到的研究,我使用的是 32 核 RHEL AWS 实例,它处理图像的速度非常快。
      收集到数据后,您可以轻松地绘制结果图表。

      2014 年 8 月 6 日 下午 14:42

  7. Phil

    我喜欢能够将 JPEG 直接传递给 cjpeg 编码器。很棒的文章,谢谢。

    2014 年 8 月 6 日 上午 10:05

    1. Robert Nyman [编辑]

      很高兴听到这个消息,谢谢!

      2014 年 8 月 6 日 下午 13:39

  8. Josiah Carlson

    文章中列出的 cjpeg 的命令行调用不正确。

    命令应为
    cjpeg -quality 80 foo.bmp > foo.jpg
    cjpeg -baseline -quality 80 foo.bmp > foo.jpg

    2014 年 8 月 6 日 上午 10:29

    1. Robert Nyman [编辑]

      我们讨论了使用 BMP 或 JPG 作为示例,并且没有在那个地方匹配命令和文本。感谢您,已更新文章!

      2014 年 8 月 6 日 上午 11:26

  9. Mark Ransom

    既然您似乎已经在测量质量指标,那么是否可以指定所需的指标值而不是质量级别?这将使结果更少依赖于图像内容,并在每种情况下获得最高的实际压缩率。

    2014 年 8 月 6 日 下午 12:11

    1. Josh Aas

      我们并没有真正根据指标进行测量,我们只是使用已知对当前配置的指标效果良好的配置选项。通过指标值指定质量是一个有趣的想法,但它很复杂,我怀疑它不会被经常使用。

      2014 年 8 月 6 日 下午 14:35

  10. Volker E.

    这是一个很棒的开发!我希望不仅看到库本身的开发,也像您写的那样,在二进制文件或任务运行器中的实现上有所发展,以面向更广泛的开发者群体。
    例如,当前在 grunt-contrib-imagemin 中的实现非常失败。

    顺便说一下,描述中仍然存在一个错误:“This will create a JPEG called “foo.jpg”” -> 应该改为“This will create a JPEG called “bar.jpg””。

    2014年8月7日 上午3:49

    1. Robert Nyman [编辑]

      感谢您的意见!我们一直在评估下一步的行动。另外,描述已修正 - 感谢。

      2014年8月7日 上午7:53

  11. Stephan B.

    我有一个用例,但它超出了10万张小图片的范围。是否有批量处理的计划?

    2014年8月7日 上午11:09

  12. Frédéric Kayser

    您可以通过设置第二个质量值来微调色度质量,例如 -quality 80,60 将把质量 80 应用于亮度 (Y) 分量,并将 60 应用于色度分量 (Cr & Cb)。要强制执行 4:2:0 色度下采样,请添加 -sample 2×2 选项(WebP 始终执行此操作)。根据我的经验,基本设置保留了过多的色度信号,降低其质量可以节省更多字节。

    2014年8月7日 上午11:53

本文的评论已关闭。