C# 自由图像JPEG的无损优化

C# 自由图像JPEG的无损优化,c#,.net,jpeg,freeimage,C#,.net,Jpeg,Freeimage,有几种工具可以在不牺牲质量的情况下优化JPEG,例如和。我一直在寻找一种通过代码(最好是在.NET中)实现的方法,目前我已经决定了,但我没有得到我想要的结果 有一个JPEG\u OPTIMIZE标志,但是你也必须设置一个质量标志,这样它就不再是无损的了 这就是我所尝试的: var image = FreeImage.Load(FREE_IMAGE_FORMAT.FIF_JPEG, fileIn, FREE_IMAGE_LOAD_FLAGS.JPEG_ACCURATE); FreeImage.Sa

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

有一个
JPEG\u 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的答案


问题是:用FreeImage可以做到吗?如果可以,怎么做?

恐怕
JPEG
是一种有损格式。即使在很小的范围内。质量标志告诉它您希望损失的范围,损失越大,压缩越好,损失越小,文件越大

  • JPEG/2000
    可以制作无损耗格式,但不太受支持
  • PNG
    支持无损压缩
但是,您可以优化JPEG文件,但这仍然会导致数据丢失,它可能是无意义的数据(即EXIF信息),但是它会丢失其中一些数据,大小增益是最小的(除非您的文件已经非常小)。浏览有关如何删除EXIF数据的教程


然而,如果您试图压缩文件的最后一滴大小,您可能会更好地切换到“更好”的格式(我松散地使用这个术语来定义更好或更差的格式是您自己的需求)。但也有其他格式支持更高的压缩率和更少的损失

当你提到优化时,我看到人们大多会想到压缩

您提到的程序(jpegtran)可以无损地优化jpeg图像,而无需解压缩和重新压缩数据。这就是你为什么不降低质量的原因。要优化jpeg,您可以执行以下操作:

  • 优化JPEG文件的哈夫曼编码层以提高压缩率
  • 在渐进式和非渐进式JPEG格式之间转换
  • 消除某些图像程序插入的非标准应用程序特定数据
  • 您也可以应用灰度、旋转或裁剪而不丢失质量,但我猜您对此不感兴趣
资料来源:维基百科


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

我认为FreeImage只支持无损转换(即
FreeImage\u JPEGTransform

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


我只能建议您查看源代码,看看是否有您可以利用的内容。

您可以使用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时,会提供一份包含相关信息的文档。

您无法避免质量上的牺牲。这是一种有损格式,你可以减轻影响,但总会有一些。也没有标准的“自动”设置可以为您校准质量。那么,您是否希望存储更少的信息?是的;更高的质量意味着更大的图像,无法回避这一事实。正如其他人已经指出的,jpeg是一种有损格式,所以。。。JPEG2000可以很好的工作,如果可以的话。你可以在不牺牲质量的情况下节省尺寸,因为它存储了很多无用的信息(对我来说)。查看我更新的问题中链接的工具和问题@BenVoigt:我期望的信息更少,但图像质量不会降低。如果你想要无损压缩,请使用PNG。是的,你是对的,但是有一些方法可以在不降低质量的情况下压缩JPEG。我已经用jpegtran和smushit的链接更新了我的答案。还有一些方法可以消除不必要的exif。@John Philip从技术上说,不,尽管前面提到的程序尽了最大的努力,但您将失去质量。这可能并不明显。JPEG不能忠实地表示你扔给它的图像,不是因为没有尝试,而是因为它使用的压缩算法。@TheZ,从技术上讲不是。你可以在不压缩/解压缩的情况下优化图像。删除某些元数据(如gps位置或特定于应用程序的数据)可以减小图像的大小,而不会降低图像质量。这是优化过程中需要注意的事情之一。还有更多。@MichalB。好的,我同意你可以减小文件大小,但是你不能用JPEG压缩图像数据,也不能降低质量。这就是我说的。此外,元数据最大不应超过约64kb…@z:64kb可以是图像大小的10倍。此外,问题是关于图像优化,你一直在谈论压缩,这表明你可能混淆了两者。是的,谢谢,我看到了。正如我提到的,我选择了图书馆FreeImage,因为我听说它可以做到这一点,我只是不知道怎么做,这是我最初的问题。