也许我有所遗漏,但我通常使用以下代码来调整/压缩JPEG图像。个人认为,根据您的源图像,结果还不错。该代码不能处理一些输入参数的边缘情况,但总体上完成了工作(如果您感兴趣,我有其他扩展方法用于裁剪和组合图像变换)。
将图像缩小至原始大小的25%并使用90%压缩。 (输出文件约30KB)
![SampleImage](https://istack.dev59.com/XLBJh.webp)
图像缩放扩展方法:
public static Image Resize(this Image image, Single scale)
{
if (image == null)
return null;
scale = Math.Max(0.0F, scale);
Int32 scaledWidth = Convert.ToInt32(image.Width * scale);
Int32 scaledHeight = Convert.ToInt32(image.Height * scale);
return image.Resize(new Size(scaledWidth, scaledHeight));
}
public static Image Resize(this Image image, Size size)
{
if (image == null || size.IsEmpty)
return null;
var resizedImage = new Bitmap(size.Width, size.Height, image.PixelFormat);
resizedImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var g = Graphics.FromImage(resizedImage))
{
var location = new Point(0, 0);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(image, new Rectangle(location, size), new Rectangle(location, image.Size), GraphicsUnit.Pixel);
}
return resizedImage;
}
压缩扩展方法:
public static Image Compress(this Image image, Int32 quality)
{
if (image == null)
return null;
quality = Math.Max(0, Math.Min(100, quality));
using (var encoderParameters = new EncoderParameters(1))
{
var imageCodecInfo = ImageCodecInfo.GetImageEncoders().First(encoder => String.Compare(encoder.MimeType, "image/jpeg", StringComparison.OrdinalIgnoreCase) == 0);
var memoryStream = new MemoryStream();
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, Convert.ToInt64(quality));
image.Save(memoryStream, imageCodecInfo, encoderParameters);
return Image.FromStream(memoryStream);
}
}
使用方法:
using(var source = Image.FromFile(@"C:\~\Source.jpg"))
using(var resized = source.Resize(0.25F))
using(var compressed = resized.Compress(90))
compressed.Save(@"C:\~\Output.jpg");
注意:
对于可能发表评论的任何人,您不能在压缩方法中创建的MemoryStream被释放之前将其dispose。如果反射到MemoryStream上的Dispose实现,实际上不必显式调用dispose是安全的。唯一的替代方案是将图像/内存流包装在实现了Image/IDisposable接口的自定义类中。