问题
i have created a function that resizes and crops a picture and then saves the resulting image file. In my development environment it works just great, but on production the resulting image is "grainy". You can see the different quality here http://test.powersport.it/canc2.aspx
Here is the code that generates the resized and cropped image
// width: width of cropped img - height: height of cropped img
System.Drawing.Bitmap thumbnail = new Bitmap(width, height);
// image: original System.Drawing.Image containing full size img
thumbnail.SetResolution(image.HorizontalResolution, image.VerticalResolution);
// size[0]: width of resized img - size[1]: height of resized image
System.Drawing.Image mini = new Bitmap(image, size[0], size[1]);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(thumbnail);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(mini, ((width - size[0]) / 2), ((height - size[1]) / 2), size[0], size[1]);
EncoderParameters encoderParameters;
encoderParameters = new EncoderParameters(1);
ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();
// img: original file name
switch (Path.GetExtension(img).ToLower())
{
case ".png": // info[4]
thumbnail.Save(dest, System.Drawing.Imaging.ImageFormat.Png);
break;
case ".bmp": // info[0]
thumbnail.Save(dest, System.Drawing.Imaging.ImageFormat.Bmp);
break;
case ".tiff": // info[3]
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
thumbnail.Save(dest, info[3], encoderParameters);
break;
case ".tif": // info[3]
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
thumbnail.Save(dest, info[3], encoderParameters);
break;
default: //jpeg info[1]
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, compression);
thumbnail.Save(dest, info[1], encoderParameters);
break;
}
Any help is appreciated. Thanks.
UPDATE: i've tried with PNG, BMP and TIFF but they have the same problem
回答1:
This is quite an interesting one, and based on the fact you are supplying compression=100
you might think that no compression at all should be applied.
Unfortunately, according to the MSDN article on setting the JPEG Compression Level:
A quality level of 0 corresponds to the greatest compression, and a quality level of 100 corresponds to the least compression.
So 100
does not mean no compression, it means the least compression possible.
As for it varying from machine to machine, this is fairly consistent - I have observed this, and there's even a number of other questions on Stack Overflow.
As the actual mechanics of the compression are handled by GDI+ (outside of the .Net Framework) then it will depend on the actual version installed on the machines.
回答2:
You're assuming that each machine has exactly the same encoders at exactly the same indexes.
It's likely each machine is actually compressing images in a different format, depspite the file extension.
WS2008 and WS2008 R2 have different graphics subsystems. In the latter, GDI+ is just a wrapper for the WIC encoders, which have a different sent of quirks.
I really hope you decide to use a library that handles these differences for you. Server-side imaging is neither simple nor intuitive, and has an endless list of pitfalls to avoid. Aside from the encoding issues you're having here, it looks like you're under the impression .NET will actually garbage collect classes from the System.Drawing
namespace. It won't, and you're going to have some serious stability issues unless every reference is inside a using(){}
clause.
来源:https://stackoverflow.com/questions/13120278/c-sharp-image-scaling-quality-different-between-dev-and-production-environment