今天遇到一个问题,从网页读取的图片,在上传使用时,太大了,不符合使用要求。因此就有了对图片进行压缩的要求。
好在图片压缩,对于C#来说,并不困难,首先加入两个引用。
using System.Drawing.Imaging;
using System.Drawing;
然后,写出如下函数:CompressionImage()
///
/// 压缩图片函数 ///
/// 图片流
/// 压缩质量0-100之間 數值越大質量越高
///
private static byte[] CompressionImage(byte[] buffer, long quality)
{
MemoryStream ms1 = new MemoryStream(buffer);
using (System.Drawing.Image img = System.Drawing.Image.FromStream(ms1, false))
{
Bitmap bitmap = new Bitmap(img);
{
ImageCodecInfo CodecInfo = GetEncoder(img.RawFormat);
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, quality);
myEncoderParameters.Param[0] = myEncoderParameter;
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, CodecInfo, myEncoderParameters);
myEncoderParameters.Dispose();
myEncoderParameter.Dispose();
return ms.ToArray();
}
}
}
}
///
/// 获取图片编码信息
///
///
///
public static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
return codec;
}
return null;
}
然后在需要进行图片压缩的地方,这样调用这个函数:
int quality = 100;
while (buffer.Count() > 307200)
{
quality = quality - 5;
buffer = CompressionImage(buffer, quality);
}
这里的quality 代表压缩质量,我这里的意思是,如果图片大小大于300KB,就增加5%的压缩质量,直到图片达到要求为止,但是经使用,发现当遇到特别大的图片的时候,会出现问题。由于这种压缩没有降低图片的分辨率,因此,当遇到高分图片,宽和高都达到4000以上的图片会出现色彩完全失真的情况,这样的图片显然不能满足使用,因此,只有再次引入如下函数。
///
/// 改变原图的分辨率
///
///
///
///
///
public static Bitmap KiResizeImage(Bitmap bmp, double lnewW, double lnewH)
{
try
{
var newW = Convert.ToInt32(lnewW);
var newH = Convert.ToInt32(lnewH);
Bitmap b = new Bitmap(newW, newH);
Graphics g = Graphics.FromImage(b);
// 插值算法的质量
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
g.Dispose();
return b;
}
catch
{
return null;
}
}
随后,我修改了CompressionImage代码,加入调用修改分辨率部分,修改后如下:
///
/// 压缩图片函数 ///
/// 图片流
/// 压缩质量0-100之間 數值越大質量越高
///
private static byte[] CompressionImage(byte[] buffer, long quality)
{
MemoryStream ms1 = new MemoryStream(buffer);
using (System.Drawing.Image img = System.Drawing.Image.FromStream(ms1, false))
{
Bitmap bitmap = new Bitmap(img);
{
double bitmapHeight = Convert.ToDouble(bitmap.Height);
double bitmapWidth =Convert.ToDouble(bitmap.Width);
bitmap = KiResizeImage(bitmap, 1024, bitmapHeight / bitmapWidth * 1024);
ImageCodecInfo CodecInfo = GetEncoder(img.RawFormat);
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, quality);
myEncoderParameters.Param[0] = myEncoderParameter;
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, CodecInfo, myEncoderParameters);
myEncoderParameters.Dispose();
myEncoderParameter.Dispose();
return ms.ToArray();
}
}
}
}
我这里简单粗暴,遇到图片统一将分辨率调整为1024宽,宽高比不变,大家可根据自己实际需要自行调整。
至此,压缩图片得到满足,无论什么样的图片,都能够压缩到300KB以内,且没有较大失真。
作者:kllsg