6

有几种工具可以在不牺牲质量的情况下优化 JPEG,例如jpegtran.exeSmush.it。我一直在寻找一种通过代码(最好是在.NET 中)来实现它的方法,我目前选择了FreeImage,但我没有得到我想要的结果。

有一个JPEG_OPTIMIZE标志,但您还必须设置一个质量标志,然后它就不再是无损的了。

这是我尝试过的:

var image = FreeImage.Load(FREE_IMAGE_FORMAT.FIF_JPEG, fileIn, FREE_IMAGE_LOAD_FLAGS.JPEG_ACCURATE);
FreeImage.Save(FREE_IMAGE_FORMAT.FIF_JPEG, image, fileOut, FREE_IMAGE_SAVE_FLAGS.JPEG_OPTIMIZE);

但它会进行压缩。我认为 FreeImage 可以优化(通过去除元数据等),但我找不到如何保持相同的压缩/图像质量。正确的方法是什么?

编辑:对于无法优化 JPEG 存在一些困惑,简短的回答是可以,因为您可以去除未使用的元数据。我不是在谈论压缩。请参阅这些线程或查看 Michael B 的答案。

用于进一步无损 jpeg 压缩的库

是否有可用的 Windows 版本的 Smush.it?

图像压缩工具

用于网络上使用的图像(jpg、gif 和 png)的图像优化器

问题是:可以用 FreeImage 完成吗?如果可以:如何?

4

4 回答 4

2

当您提到优化时,我看到人们大多会考虑压缩...

您提到的程序(jpegtran)可以无损地优化jpeg图像,而无需解压缩和重新压缩数据。这就是为什么你不会失去质量。您可以做些什么来优化 jpeg 是:

  • 优化 JPEG 文件的 Huffman 编码层以增加压缩率,
  • 在渐进式和非渐进式 JPEG 格式之间转换,
  • 消除一些图像程序插入的非标准应用程序特定数据
  • 你也可以应用灰度、旋转或裁剪而不会失去质量,但我猜你对此不感兴趣。

来源:维基百科。

我从来没有做过,所以我手头没有任何东西,但我很确定有一个图书馆可以为你做这件事。否则,自己制作东西应该不会那么困难。

于 2012-07-10T06:18:52.397 回答
2

我认为 FreeImage 只支持无损转换(即FreeImage_JPEGTransform)。

这可以保存到不同的文件,但不幸的是,似乎没有办法在新文件上设置任何保存标志以允许剥离元数据等。

我只能建议您查看源代码,看看是否有任何您可以自己利用的东西。

于 2012-07-10T12:36:59.100 回答
1

恐怕JPEG是有损格式。即使是很小的规模。质量标志告诉它您希望损失的比例,压缩越大,损失越小,文件越大,损失越小。

  • JPEG/2000可以做无损格式,但不太受支持
  • PNG支持无损压缩。

但是,您可以优化 JPEG 文件,但这仍然会导致数据丢失,它可能是无意义的数据(即 EXIF 信息),但它会丢失其中一些,大小增益很小(除非您的文件已经非常小) . 在这里查看有关如何删除 EXIF 数据的教程。

但是,如果您尝试从文件中挤出最后一滴大小,则最好切换到“更好”的格式(我松散地使用该术语,因为定义更好或更差格式是您自己的要求)。但是还有其他格式支持更高的压缩率和更少的损失。

于 2012-07-09T22:01:33.690 回答
1

您可以使用 FreeImage 删除元数据,但是对于 jpeg,图像将在保存时重新压缩,并会导致图像质量下降。

' by default, FreeImage will have copied the metadata to the new image
If Not (args.CopyMetadata) Then
    Dim tag As New FreeImageAPI.FITAG
    FreeImage.SetMetadata(FREE_IMAGE_MDMODEL.FIMD_COMMENTS, dib2, Nothing, tag)
    FreeImage.SetMetadata(FREE_IMAGE_MDMODEL.FIMD_IPTC, dib2, Nothing, tag)
    FreeImage.SetMetadata(FREE_IMAGE_MDMODEL.FIMD_XMP, dib2, Nothing, tag)
    ' value of 11 is for FIMD_EXIF_RAW
    FreeImage.SetMetadata(DirectCast(11, FreeImageAPI.FREE_IMAGE_MDMODEL), dib2, Nothing, tag)
    FreeImage.DeleteTag(tag)
End If

If File.Exists(targetFile) Then
    File.Delete(targetFile)
End If

FreeImage.Save(FREE_IMAGE_FORMAT.FIF_JPEG, dib2, targetFile, FREE_IMAGE_SAVE_FLAGS.JPEG_OPTIMIZE Or FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD)

如果要从 FIF_JPEG 以外的文件类型中删除元数据,则应查阅文档以查看哪些是可写的。

要在不影响图像的情况下删除元数据,您需要查看 jpeg 文件交换格式并仅提取所需的数据。如果您碰巧有 Photoshop 6 安装 CD(6,而不是 CS6),则在安装 PS6 SDK 时可以获得包含相关信息的文档。

于 2013-09-05T14:33:16.680 回答