使用c#进行高质量JPEG压缩

时间:2009-11-03 20:09:48

标签: c# .net image compression jpeg

我正在使用C#并希望使用JPEG格式保存图像。但是,.NET会降低图像的质量,并通过压缩来保存它们。

我想保存原始质量和尺寸的文件。我使用以下代码,但压缩和质量不像原始的。

Bitmap bm = (Bitmap)Image.FromFile(FilePath); 
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 
ImageCodecInfo ici = null; 

foreach (ImageCodecInfo codec in codecs)
{ 
    if (codec.MimeType == "image/jpeg") 
    ici = codec; 
} 

EncoderParameters ep = new EncoderParameters(); 
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100); 
bm.Save("C:\\quality" + x.ToString() + ".jpg", ici, ep);

我正在归档工作室照片和质量和压缩是非常重要的。感谢。

6 个答案:

答案 0 :(得分:19)

库内置的.Net编码器(至少是微软提供的默认Windows库)非常糟糕:

http://b9dev.blogspot.com/2013/06/nets-built-in-jpeg-encoder-convenient.html

部分更新

我现在正在使用an approach outlined here,它使用ImageMagick进行调整大小,然后使用jpegoptim进行最终压缩,效果要好得多。我意识到这是一个部分答案,但我会在一次允许的情况下对此进行扩展。

旧答案

ImageMagick是我迄今为止发现的最佳选择。它执行相对稳定的jpeg压缩。

http://magick.codeplex.com/

它有几个缺点:

  1. 它更好但不完美。特别是,它的色度子采样设置为90%或更高的高细节,然后跳到更低的细节级别 - 一个可以引入大量伪像。如果你想忽略子采样,这实际上非常方便。但是如果你想要50%的高细节子采样,你将面临更大的挑战。它仍然不会达到Photoshop或Google PageSpeed的质量/压缩级别。

  2. 它在服务器上有一个特殊的部署负担,很容易错过。它需要安装Visual Studio 2008 SDK lib。这个lib可以在任何带有Visual Studio的开发机器上使用,但是你第一次点击服务器它就会出现一个模糊的错误。这是潜伏的陷阱之一,大多数人都没有脚本/自动化,你将在未来的服务器迁移期间绊倒它。

  3. 最早的答案

    我挖了一个项目,通过翻译C项目来实现C#JPEG编码器:

    http://www.codeproject.com/Articles/83225/A-Simple-JPEG-Encoder-in-C

    我稍微简化了一下:

    https://github.com/b9chris/ArpanJpegEncoder

    它产生比.Net内置更高质量的JPEG,但仍然不如Gimp或Photoshop。文件大小也往往更大。

    BitMiracle's implementation几乎与.Net内置相同 - 相同的质量问题。

    可能只是包装现有的开源实现,例如Google's jpeg_optimizer in PageSpeed Tools - 看似libjpeg,将是最有效的选择。

    更新

    ArpanJpegEncoder一旦部署就会​​出现问题 - 也许我需要增加代码的信任级别,或者可能还有其他事情发生。在本地,它可以很好地写入图像,但是一旦部署,我每次都会从中获得一张空白的黑色图像。如果我确定原因,我会更新。只是警告其他人考虑它。

答案 1 :(得分:10)

看起来您将质量设置为100%。这意味着不会有压缩。

如果更改压缩级别(80,50等)并且您对质量不满意,则可能需要尝试使用其他图像库。 LEADTools有一个很好的(非免费)引擎。

更新:作为一名评论者提到,使用JPEG时,100%质量仍然不意味着无损压缩。加载图像,对其执行某些操作,然后再次保存,最终会导致图像质量下降。如果您需要更改和保存图像而不丢失任何数据,则需要使用无损格式,如TIFF,PNG或BMP。我会使用压缩的TIFF(因为即使它被压缩它仍然是无损的)或PNG。

答案 2 :(得分:6)

压缩和质量始终是一种权衡。

JPEG总是有损。

您可能需要考虑使用PNG并使用PNGCrush缩小文件或PNGauntlet

答案 3 :(得分:2)

关于在.NET中设置压缩级别,请检查此链接(包括所有内容):http://msdn.microsoft.com/en-us/library/bb882583.aspx

回答你的问题: 通常你会将用户上传的图像保存为PNG,然后你用这个PNG作为基础来生成不同大小的JPG(你只在JPG上放一个水印,而不是在原始的PNG上!) 这样做的好处是:如果您稍后为平台更改图像尺寸,则会保存原始PNG,并且根据此可以重新计算任何新图像尺寸。

答案 4 :(得分:0)

  

必须将文件保存为其原始质量和尺寸

这没有多大意义。当您使用有损压缩时,您将根据定义丢失一些信息。压缩图像的目的是减小文件大小。如果你需要高质量而jpeg没有为你做这件事你可能不得不采用某种类型的无损压缩,但你的文件大小不会减少太多。您总是可以尝试使用“标准”库来压缩到jpeg(libjpeg)并查看是否会给您带来任何不同的结果(我对此表示怀疑,但我不知道.NET正在使用什么。)

答案 5 :(得分:0)

压缩jpeg格式本质上会降低质量。也许您应该研究文件压缩,例如#ziplib。您可以对一组文件进行合理的压缩。