在 .NET 中使用 GDI 调整图像大小会导致饱和度较低

发布于 2024-08-07 21:19:49 字数 1530 浏览 3 评论 0原文

我正在解决一个问题:当我使用 GDI 操作调整后的图像时,它们会失去颜色饱和度。

我将 JPG 作为原始图片加载,调整其大小,结果图像的饱和度(颜色强度)比原始图片低很多。我可以做些什么来改善这一点?这是我的代码:

using ( var original = System.Drawing.Image.FromStream( new MemoryStream( image.RawData ) ) )
{
    using ( var dst = new Bitmap( width, height, PixelFormat.Format32bppArgb ) )
    {
        using ( var g = Graphics.FromImage( dst ) )
        {
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;

            g.DrawImage( original, 0, 0, dst.Width, dst.Height );
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.DrawImage( original, 0, 0, dst.Width, dst.Height );

            var jpgEncoder = GetEncoder( ImageFormat.Jpeg );
            var myEncoderParameters = new EncoderParameters( 1 );
            var quality = 95;
            var myEncoderParameter = new EncoderParameter( Encoder.Quality, quality );
            myEncoderParameters.Param[0] = myEncoderParameter;

            dst.Save( buffer, jpgEncoder, myEncoderParameters );
        }
    }
}

我尝试过使用不同的像素格式,删除所有过滤器等,但我总是得到相同的结果。这是 GDI 的一些已知问题,还是我错过了什么?

添加在: 在 Paint.NET 中打开图像时,即使没有重新缩放,我也会遇到同样的低饱和度问题,所以我猜这是 GDI+ 加载图像(jpg)的方式?

该图像是从 Photoshop 中保存的,颜色配置文件为 sRGB,但是 JPG 没有嵌入有关颜色配置文件的信息。即使确实如此,我相信 Firefox 也不会遵守它们(这是我测试过的)

更多测试表明,与 Firefox 相比,它在 IE8 中看起来有所不同。 JPG 似乎支持颜色配置文件,但大多数应用程序并不遵守它们。然而FF3.5似乎做到了。图像上是 Adob​​e RGB,而不是 sRGB。

I'm fighting an issue where my resized images looses color saturation when I manipulate them using GDI.

I'm loading an JPG as original, resize it and the resulting image has a lot less saturation (color intensity) than the original picture. What can I do to improve that? this is my code:


using ( var original = System.Drawing.Image.FromStream( new MemoryStream( image.RawData ) ) )
{
    using ( var dst = new Bitmap( width, height, PixelFormat.Format32bppArgb ) )
    {
        using ( var g = Graphics.FromImage( dst ) )
        {
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;

            g.DrawImage( original, 0, 0, dst.Width, dst.Height );
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.DrawImage( original, 0, 0, dst.Width, dst.Height );

            var jpgEncoder = GetEncoder( ImageFormat.Jpeg );
            var myEncoderParameters = new EncoderParameters( 1 );
            var quality = 95;
            var myEncoderParameter = new EncoderParameter( Encoder.Quality, quality );
            myEncoderParameters.Param[0] = myEncoderParameter;

            dst.Save( buffer, jpgEncoder, myEncoderParameters );
        }
    }
}

I've tried with different pixelformats, removing all filters etc but I always get the same result. Is this some known issue with GDI, or have I missed something?

Addon:
When opening the image in Paint.NET, I get the same issue with low saturation, even without rescaling, so I guess it's the way GDI+ loads images (jpgs)?

This image was saved from photoshop with color profile sRGB, but afaik JPG doesn't have info about colorprofiles embedded. And even if it did, I believe that firefox doesn't obey them (which is what I've tested with)

More testing shows that it looks different in IE8 in contrast to firefox. JPGs seems to support color profiles, but most applications doesn't obey them. FF3.5 however, seems to do it. And it was Adobe RGB, not sRGB on the image.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

春花秋月 2024-08-14 21:19:49

我自己找到了答案。这与 GDI+ 中默认情况下未应用的颜色配置文件有关。许多人声称您无法使用 GDI 自动应用颜色配置文件,但显然,我需要做的唯一更改是:

using ( var original = System.Drawing.Image.FromStream( new MemoryStream( image.RawData ) ) )

using ( var original = new Bitmap( new MemoryStream( image.RawData ), true ) )

显然,Bitmap 是 Image 的派生类,Bitmap 的构造函数可以采用既是一个流,也是一个“useIcm”的布尔值。这对我来说很有效。

I found the answer myself. It has to do with color-profiles not beeing applied by default in GDI+. Many people claims that you cannot automatically apply color-profiles using GDI, but apparently, the only change I needed to do was this:

using ( var original = System.Drawing.Image.FromStream( new MemoryStream( image.RawData ) ) )

to

using ( var original = new Bitmap( new MemoryStream( image.RawData ), true ) )

Apparently, Bitmap was a derived class of Image, and the constructor for Bitmap can take both a stream aswell as a boolean for "useIcm". That did the trick for me.

泪冰清 2024-08-14 21:19:49

我有一个使用的图像重新缩放代码,但我没有看到你提到的效果。

我看到的主要区别是我使用 Format24bppRgb 而不是 Format24bppARgb

请记住,JPG 无论如何都没有 Alpha 通道(据我所知)

I have an image-rescaling code I use, and I don't see the effect you mention.

the main difference I see is that I use Format24bppRgb and not Format24bppARgb

Keep in mind that JPG has no Alpha channel anyway (afaik)

紫竹語嫣☆ 2024-08-14 21:19:49

从另一个角度来看,如果您想减轻自己这样做的痛苦,我强烈推荐 ImageResizer 。它甚至负责磁盘缓存。

Coming at this from another angle, I would highly recommend ImageResizer if you want to take the pain out of doing this yourself. It even takes care of disk caching.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文