简体   繁体   English

使用C#进行高质量的JPEG压缩

[英]High quality JPEG compression with c#

I am using C# and want to save images using JPEG format. 我正在使用C#,并希望使用JPEG格式保存图像。 However .NET reduces quality of the images and saves them with compression that is not enough. 但是,.NET会降低图像质量,并通过不够的压缩来保存图像。

I want to save files with their original quality and size. 我要保存文件的原始质量和大小。 I am using the following code but compression and quality are not like the original ones. 我正在使用以下代码,但是压缩和质量与原始代码不同。

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);

I am archiving studio photos and quality and compression is very important. 我正在存档工作室照片,质量和压缩率非常重要。 Thanks. 谢谢。

The .Net encoder built-in to the library (at least the default Windows library provided by Microsoft) is pretty bad: 库中内置的.Net编码器(至少是Microsoft提供的默认Windows库)非常糟糕:

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

Partial Update 部分更新

I'm now using an approach outlined here , that uses ImageMagick for the resize then jpegoptim for the final compression, with far better results. 我现在使用的是这里概述的方法 ,该方法使用ImageMagick调整大小,然后使用jpegoptim进行最终压缩,效果更好。 I realize that's a partial answer but I'll expand on this once time allows. 我意识到这是部分答案,但在允许的情况下我将对此进行扩展。

Older Answer 较旧的答案

ImageMagick is the best choice I've found so far. 到目前为止,ImageMagick是我找到的最佳选择。 It performs relatively solid jpeg compression. 它执行相对可靠的jpeg压缩。

http://magick.codeplex.com/ http://magick.codeplex.com/

It has a couple downsides: 它有一些缺点:

  1. It's better but not perfect. 更好,但并不完美。 In particular, its Chroma subsampling is set to high detail at 90% or above, then jumps down to a lower detail level - one that can introduce a lot of artifacts. 特别是,其色度二次采样设置为90%或更高的高细节,然后跳到较低的细节级别-可能会引入很多伪像。 If you want to ignore subsampling, this is actually pretty convenient. 如果要忽略二次采样,这实际上很方便。 But if you wanted high-detail subsampling at say, 50%, you have a larger challenge ahead. 但是,如果您想以50%的比例进行高细节子采样,则面临更大的挑战。 It also still won't quite hit quality/compression levels of Photoshop or Google PageSpeed. 它还仍然不会完全达到Photoshop或Google PageSpeed的质量/压缩级别。

  2. It has a special deployment burden on the server that's very easy to miss. 它对服务器有特殊的部署负担,这很容易错过。 It requires a Visual Studio 2008 SDK lib installed. 它需要安装Visual Studio 2008 SDK库。 This lib is available on any dev machine with Visual Studio on it, but then you hit the server for the first time and it implodes with an obscure error. 此lib可在装有Visual Studio的任何开发机上使用,但是您第一次访问服务器时,它会因模糊的错误而崩溃。 It's one of those lurking gotchas most people won't have scripted/automated, and you'll trip over it during some future server migration. 它是大多数人不会编写脚本/自动执行的潜伏陷阱之一,在以后的某些服务器迁移中,您将不胜其烦。

Oldest Answer 最早的答案

I dug around and came across a project to implement a C# JPEG encoder by translating a C project over: 我四处挖掘并遇到了一个项目,该项目通过将C项目转换为以下内容来实现C#JPEG编码器:

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

which I've simplified slightly: 我已经稍微简化了一下:

https://github.com/b9chris/ArpanJpegEncoder https://github.com/b9chris/ArpanJpegEncoder

It produces much higher quality JPEGs than the .Net built-in, but still is not as good as Gimp's or Photoshop's. 它比内置的.Net产生更高质量的JPEG,但是仍然不如Gimp或Photoshop更好。 Filesizes also tend to be larger. 文件大小也往往更大。

BitMiracle's implementation is practically identical to the .Net built-in - same quality problems. BitMiracle的实现实际上与.Net内置的相同质量问题相同。

It's likely that just wrapping an existing open source implementation, like Google's jpeg_optimizer in PageSpeed Tools - seemingly libjpeg underneath, would be the most efficient option. 仅包装现有的开源实现(例如Google在PageSpeed Tools中的jpeg_optimizer-似乎在下面的libjpeg )可能是最有效的选择。

Update 更新资料

ArpanJpegEncoder appears to have issues once it's deployed - maybe I need to increase the trust level of the code, or perhaps something else is going on. ArpanJpegEncoder部署后似乎出现了问题-也许我需要提高代码的信任级别,或者可能正在发生其他情况。 Locally it writes images fine, but once deployed I get a blank black image from it every time. 在本地它可以很好地写入图像,但是一旦部署,我每次都会得到一个空白的黑色图像。 I'll update if I determine the cause. 如果确定原因,我将进行更新。 Just a warning to others considering it. 只是对其他考虑者的警告。

It looks like you're setting the quality to 100%. 您好像将质量设置为100%。 That means that there will be no compression. 这意味着将没有压缩。

If you change the compression level (80, 50, etc.) and you're unsatisifed with the quality, you may want to try a different image library. 如果更改了压缩级别(80、50等),但对质量不满意,则可能要尝试使用其他图像库。 LEADTools has a good (non-free) engine. LEADTools具有良好的引擎(非免费)。

UPDATE: As a commenter mentioned, 100% quality still does not mean lossless compression when using JPEG. 更新:如评论员所述,使用JPEG时100%的质量仍然并不意味着无损压缩。 Loading the image, doing something to it, and then saving it again will ultimately result in image degradation. 加载图像,对其进行处理,然后再次保存,最终将导致图像质量下降。 If you need to alter and save an image without losing any of the data you need to use a lossless format such as TIFF, PNG or BMP. 如果您需要更改和保存图像而不丢失任何数据,则需要使用无损格式,例如TIFF,PNG或BMP。 I'd go with compressed TIFF (since it's still lossless even though it's compressed) or PNG. 我会使用压缩的TIFF(因为即使压缩也仍然无损)或PNG。

Compression and quality are always a trade off. 压缩和质量始终是折衷方案。

JPEGs are always going to be lossy. JPEG总是有损的。

You may want to consider using PNG and minifying the files using PNGCrush or PNGauntlet 您可能要考虑使用PNG并使用PNGCrush或PNGauntlet缩小文件

Regarding the setup of the compression level in .NET, please check this link (everything included): http://msdn.microsoft.com/en-us/library/bb882583.aspx 关于.NET中压缩级别的设置,请检查此链接(包括所有内容): http : //msdn.microsoft.com/zh-cn/library/bb882583.aspx

Rearding your question: Usually you will save the uploaded image from users as PNG, then you use this PNG as base to generate your JPGs with different sizes (and you put a watermark ONLY on the JPGs, never on the original PNG!) Advantage of this is: if you change your images-dimensions later on for your platform, you have the original PNG saved and based on this you can re-compute any new image sizes. 提出您的问题:通常,您会将用户上传的图像另存为PNG,然后以该PNG为基础来生成具有不同大小的JPG(并且仅在JPG上加水印,而不在原始PNG上加水印!)这是:如果以后在平台上更改图像尺寸,则将保存原始PNG,并基于此可以重新计算任何新图像尺寸。

It must save the file like its orjinal quality and size 它必须保存文件,如其原始质量和大小

That doesn't make a lot of sense. 那没有什么意义。 When you are using lossy compression you are going to lose some information by definition. 使用有损压缩时,根据定义,您将丢失一些信息。 The point of compressing an image is to reduce the file size. 压缩图像的目的是减小文件大小。 If you need high quality and jpeg isn't doing it for you you may have to go with some type of lossless compression, but your file sizes will not be reduced by much. 如果您需要高质量,而jpeg不能满足您的需要,则可能需要进行某种类型的无损压缩,但是文件大小不会减少太多。 You could always try using the 'standard' library for compressing to jpeg ( libjpeg) and see if that gives you any different results (I doubt it, but I don't know what .NET is using under the hood.) 您总是可以尝试使用“标准”库将其压缩为jpeg( libjpeg) ,看看是否能给您带来任何不同的结果(我对此表示怀疑,但我不知道.NET在后台使用了什么。)

Compressing the jpeg format by its very nature reduces quality. 通过本质上压缩jpeg格式会降低质量。 Perhaps you should look into file compression, such as #ziplib . 也许您应该研究文件压缩,例如#ziplib You may be able to get a reasonable compression over a group of files. 您也许可以对一组文件进行合理的压缩。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM