收缩图像时如何才能获得更好的效果

我正在用c#缩小图像,我将我的方法与Photoshop cs5中的最佳方法进行了比较,无法复制它。

在PS我使用bicubic锐化,看起来非常好。 但是,当尝试在c#中做同样的事情时,我得不到高质量的结果。 我尝试了双三次插值以及HQ双三次,平滑模式HQ /无/ AA。 合成模式,我尝试了大约50种不同的变化,每一种都非常接近右边的图像。

你会注意到她背面和标题周围的像素化,以及作者的名字不太好。

(左边是PS,右边是c#。)

在此处输入图像描述

似乎c#bicubic即使平滑设置为无,也会进行太多平滑处理。 我一直在玩以下代码的许多变体:

g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = PixelOffsetMode.None; g.SmoothingMode = SmoothingMode.None; 

编辑:这里要求的是起始图像(1mb)。 在此处输入图像描述

也许我遗漏了一些东西,但我通常使用下面的代码来调整JPEG图像的大小/压缩。 就个人而言,我认为根据您的源图像,结果非常好。 代码不处理有关输入参数的一些边缘情况,但总体上完成了工作(我有额外的扩展方法用于裁剪,并且如果感兴趣则组合图像变换)。

图像缩放至原始大小的25%并使用90%压缩。 (~30KB输出文件)

SampleImage

图像缩放扩展方法:

 public static Image Resize(this Image image, Single scale) { if (image == null) return null; scale = Math.Max(0.0F, scale); Int32 scaledWidth = Convert.ToInt32(image.Width * scale); Int32 scaledHeight = Convert.ToInt32(image.Height * scale); return image.Resize(new Size(scaledWidth, scaledHeight)); } public static Image Resize(this Image image, Size size) { if (image == null || size.IsEmpty) return null; var resizedImage = new Bitmap(size.Width, size.Height, image.PixelFormat); resizedImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (var g = Graphics.FromImage(resizedImage)) { var location = new Point(0, 0); g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(image, new Rectangle(location, size), new Rectangle(location, image.Size), GraphicsUnit.Pixel); } return resizedImage; } 

压缩扩展方法:

 public static Image Compress(this Image image, Int32 quality) { if (image == null) return null; quality = Math.Max(0, Math.Min(100, quality)); using (var encoderParameters = new EncoderParameters(1)) { var imageCodecInfo = ImageCodecInfo.GetImageEncoders().First(encoder => String.Compare(encoder.MimeType, "image/jpeg", StringComparison.OrdinalIgnoreCase) == 0); var memoryStream = new MemoryStream(); encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, Convert.ToInt64(quality)); image.Save(memoryStream, imageCodecInfo, encoderParameters); return Image.FromStream(memoryStream); } } 

用法:

  using(var source = Image.FromFile(@"C:\~\Source.jpg")) using(var resized = source.Resize(0.25F)) using(var compressed = resized.Compress(90)) compressed.Save(@"C:\~\Output.jpg"); 

注意:对于可能发表评论的任何人,您不能在处理图像之前处置在Compress方法中创建的MemoryStream。 如果您反映在MemoryStream上的Dispose的实现,它实际上是保存到不显式调用dispose。 唯一的替代方法是将图像/内存流包装在实现Image / IDisposable的类的自定义实现中。

看一下JPEG工件的数量,特别是在图像的顶部,我认为你将jpg压缩设置为高。 这会导致较小的(文件大小)文件,但会降低图像质量,并且似乎会增加更多模糊。

你能尝试以更高的质量保存吗? 我假设包含CompositingQuality.HighQuality的行已经这样做了,但也许你可以找到更高质量的模式。 Photoshop和C#之间的文件大小有何不同? 在保存并重新打开后,Photoshop图像如何显示? 只是在Photoshop中resize不会引入任何jpg数据丢失。 在将图像保存为jpg然后关闭并重新打开后,您才会注意到。

我偶然发现了这个问题。

我使用此代码不使用jpeg的压缩,它像PS版本一样出现:

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