Image resize with GDI in .NET gives low saturation

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.


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.


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 Format24bpp A Rgb

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


Coming at this from another angle, I would highly recommend http://nathanaeljones.com/products/asp-net-image-resizer/ if you want to take the pain out of doing this yourself. It even takes care of disk caching!

链接地址: http://www.djcxy.com/p/50290.html

上一篇: 对于没有陷印异常的双色TIFF图像的.NET测试?

下一篇: 在.NET中使用GDI调整图像大小会降低饱和度