缩小图像质量 - c#

我编写了一个简单的PhotoEditor帮助程序类,以缩小比例和裁剪上传到我的网站的图像。一切正常,但是将图像保存到文件时,我发现质量不令人满意。我已经阅读了您可以调整的不同设置,以下是我调整大小的设置,裁剪是相同的。

    public Image ResizeImage(Image imgToResize, Size size)
    {
        int sourceWidth = imgToResize.Width;
        int sourceHeight = imgToResize.Height;

        float nPercentW = (size.Width/(float) sourceWidth);
        float nPercentH = (size.Height/(float) sourceHeight);

        float nPercent = nPercentH < nPercentW ? nPercentH : nPercentW;

        var destWidth = (int) (sourceWidth*nPercent);
        var destHeight = (int) (sourceHeight*nPercent);

        var src = imgToResize;

        using (var dst = new Bitmap(destWidth, destHeight, imgToResize.PixelFormat))
        {
            dst.SetResolution(imgToResize.HorizontalResolution, imgToResize.VerticalResolution);

            using (var g = Graphics.FromImage(dst))
            {
                var mime = GetMimeType(imgToResize);
                ImageFormat format;
                if (mime == "image/gif" || mime == "image/png")
                {
                    //convert all gif to png, better resize quality
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.DrawImage(src, 0, 0, dst.Width, dst.Height);
                    format = ImageFormat.Png;
                }
                else
                {
                    //jpeg
                    g.CompositingQuality = CompositingQuality.HighQuality;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    format = ImageFormat.Jpeg;
                }
                g.DrawImage(src, 0, 0, dst.Width, dst.Height);

                // At this point the new bitmap has no MimeType
                // Need to output to memory stream
                var m = new MemoryStream();
                dst.Save(m, format);

                var img = Image.FromStream(m);

                return img;
            }
        }
    }

如您所见,我在为插值,平滑化等使用建议的设置。我还在以100质量保存jpeg。

即使缩小到原始大小的75%,生成的图像也具有明显的模糊和伪影。我环顾四周,这是推荐的方式。我发现了一种简单的调整大小的方法,因此决定尝试一下。

Bitmap NewImg = new Bitmap(original, new Size(387,257));
editor.SaveImage(@"C:\simpleResize.jpg", NewImg, ImageFormat.Jpeg);

出人意料的是,这会产生更好的图像,尽管它的内存占用量要大得多〜30%。

我的问题是,有什么区别,我在调整大小例程中缺少什么设置,可以解释较丑的结果。我想让我的调整大小例程产生与简单调整大小完全相同的结果。

非常感谢您的帮助。这是我第一次涉足图像处理。

编辑

简单调整大小(82KB)

simple http://img189.imageshack.us/img189/2137/simpleresize.jpg

我的大小调整(55KB)

complex http://img12.imageshack.us/img12/4023/complexresize.jpg

参考方案

我首先想到的是.NET的jpeg编码器即使在最高质量设置下也使用色度二次采样,因此颜色信息以半分辨率存储。据我所知,该设置是硬编码的。但这并不能解释为什么在第二个示例中您将获得更好的质量。除非在第二个版本中没有使用抗锯齿功能,否则它会提供更清晰(但质量较低)的图像,并且不会引起人为干扰。

编辑:dst.Save(m,格式);看起来像你的问题。您使用默认质量(不是100%)将其编码为jpeg,然后立即将其解码回图像。 dst已经是一个Image(Bitmap类继承自Image),因此您可以按原样返回它

在Python和C++之间传输数据而无需写入Windows和Unix文件 - python

我有预先存在的python和C ++文件,其中python文件定义了许多点,而C ++代码利用其现有库进行了所需的计算。最终产品是C ++代码写入的文件。我正在寻找一种在python中获取2000点列表的方法,将其传递给函数,然后执行所有C ++代码并输出我需要的文件。其他注意事项。这必须是可以在Linux或Windows机器上工作的东西,并且最少安装新插件…

Java值加变量++ - java

考虑以下代码int val1 = 3; val1++; int val2 = val1++; System.out.println(val1); System.out.println(val2); Val1值= 5;Val2值= 4;为什么Val1的值是“ 5”?据我了解,应该为4,因为:在第1行,它的赋值为3,在第2行,通过val1 ++加上1,结果val…

如何锁定终端运行的perl,obj c,c++,python和ruby等脚本的源代码? - python

我想出售我在perl,obj c,c ++,python,ruby,bash,php等中制作的脚本等它们都在终端中运行。 (Linux)如何锁定源代码,以便无需人们访问源代码即可分发我的脚本..?换句话说,如何将在Terminal中运行的程序的源代码锁定,以便人们可以使用该程序(如果该代码已下载到他们的Linux机器上,但他们无法访问实际的源代码)?例:ex…

如何使用C#或C / C++在Windows 7中获取智能卡阅读器名称? - c#

我正在尝试制作一个将使用C .dll(不幸的是,.dll没有好的文档)来访问智能卡的C#程序。 .dll的功能之一使用读取器的名称作为参数。我的问题是我不知道该如何命名。在寻找答案之后,我在这里的示例中发现了与我所需要的东西类似的内容:http://msdn.microsoft.com/en-us/library/aa379803%28VS.85%29.as…

标签名称属性带有+和引号 - javascript

当数据从数据库到网格中的视图时,标签名称属性带有+和引号,但我不希望这样做:以下是我正在执行的代码@if (ViewBag.ExperienceDetailsGrid != null) { var ExprowCount = 1; Foreach (var item in ViewBag.ExperienceDetailsGrid) { <tr cla…