C#图片缩放出伪影,如何实现类似Photoshop的高质量缩放?
图片缩放伪影问题及解决方案咨询
我尝试了各类图片缩小代码,均出现伪影问题,但手动使用Photoshop处理时无此情况,求更多修复方案。另外注意到Photoshop导出位图时可选择「progressive」模式,想知道C#中是否有类似功能?
效果对比
- Photoshop缩放效果(1080p→480p):

- 代码缩放效果(1080p→480p):

图片其他区域情况类似,衣领处的伪影是代码问题的典型示例。
当前使用的ResizeImage函数代码
public static Bitmap ResizeImage(Image image, int width, int height) { var destRect = new System.Drawing.Rectangle(0, 0, width, height); var destImage = new System.Drawing.Bitmap(width, height); destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (var graphics = System.Drawing.Graphics.FromImage(destImage)) { graphics.CompositingMode = CompositingMode.SourceCopy; graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; using (var wrapMode = new System.Drawing.Imaging.ImageAttributes()) { wrapMode.SetWrapMode(WrapMode.TileFlipXY); graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel, wrapMode); } } return destImage; }
原始图片参考

修复方案及相关解答
1. 调整插值模式与预处理
你当前用的HighQualityBicubic并非所有场景都最优,可以尝试切换为InterpolationMode.HighQualityBilinear,部分边缘场景下表现更柔和;另外缩放前给原图加轻微高斯模糊,能减少高频噪点带来的锯齿:
// 缩放前给原图做轻度模糊 private static Image ApplyLightBlur(Image image) { Bitmap blurred = new Bitmap(image.Width, image.Height); using (Graphics g = Graphics.FromImage(blurred)) { // 5x5均值模糊矩阵,弱化细节噪点 float[][] blurMatrix = new float[5][]; float weight = 1f / 25f; for (int i = 0; i < 5; i++) { blurMatrix[i] = new float[] { weight, weight, weight, weight, weight }; } using (var attributes = new System.Drawing.Imaging.ImageAttributes()) { attributes.SetColorMatrix(new System.Drawing.Imaging.ColorMatrix(blurMatrix)); g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); } } return blurred; }
调用时先对原图做模糊,再传入ResizeImage函数即可。
2. 改用专业图像处理库
System.Drawing的原生缩放算法精度有限,推荐用ImageSharp或Magick.NET这类专业库,它们的插值算法更接近Photoshop的效果:
- ImageSharp示例(用Lanczos3插值,缩小图像时细节保留+抗锯齿表现更优):
using SixLabors.ImageSharp; using SixLabors.ImageSharp.Processing; public static Image ResizeWithImageSharp(Image image, int width, int height) { return image.Clone(ctx => ctx.Resize(width, height, KnownResamplers.Lanczos3)); }
3. 关于Progressive模式的说明
Photoshop的「progressive」是JPEG的编码方式,和缩放质量无关,仅影响图片加载时的显示顺序(从模糊到清晰渐进加载)。C#中保存JPEG时可以开启这个选项:
// 保存图片时启用Progressive模式 destImage.Save("output.jpg", GetProgressiveJpegEncoder()); private static System.Drawing.Imaging.ImageCodecInfo GetProgressiveJpegEncoder() { foreach (var codec in System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()) { if (codec.FormatID == System.Drawing.Imaging.ImageFormat.Jpeg.Guid) { var encoderParams = new System.Drawing.Imaging.EncoderParameters(1); encoderParams.Param[0] = new System.Drawing.Imaging.EncoderParameter( System.Drawing.Imaging.Encoder.SaveFlag, (long)System.Drawing.Imaging.EncoderValue.Progressive ); return codec; } } return null; }
内容的提问来源于stack exchange,提问作者Sparks
相关产品推荐
相关产品推荐

