创建图像缩略图的方法
创建缩略图的方法有多种,最简单的是使用.net自带的方法创建缩略图,或者使用重绘试,如需要压缩处理可以使用JPEG压缩一下.
下面我使用几种方法测试了一下,使用.net自带的方法创建缩略图能很好地保证质量,重绘方式创建的缩略图质量稍差,特别是处理小图片,如头像,局部细节变得模糊.重绘虽然相对.net缩略图能小一点但质量真的勉强。
Code
/// <summary>
/// 使用.net自带的提取缩略图方法创建缩略图
/// </summary>
/// <param name="imageStream">图像输入流</param>
/// <param name="thumbWi">指定缩略图宽度</param>
/// <param name="thumbHi">指定缩略图高度</param>
/// <returns>返回缩略图字节数据</returns>
private byte[] getImageByteData(Stream imageStream, int thumbWi, int thumbHi)
{
System.Drawing.Image image = System.Drawing.Image.FromStream(imageStream);
int height = thumbHi;
int width = thumbWi;
if (image.Height > height || image.Width > width)
{
//变缩略图
System.Drawing.Image.GetThumbnailImageAbort callb = null;
//使用指定大小提取缩略图
System.Drawing.Image thumbnailImage = image.GetThumbnailImage(thumbWi, thumbHi, callb, new System.IntPtr());
image = thumbnailImage;
}
MemoryStream Stream = new MemoryStream();
image.Save(Stream, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] byteData = Stream.ToArray();
return byteData;
}
/// <summary>
/// 使用重绘方式创建缩略图
/// </summary>
/// <param name="source">源图</param>
/// <param name="thumbWi">指定缩略图宽度</param>
/// <param name="thumbHi">指定缩略图高度</param>
/// <param name="maintainAspect">是否保持长宽比例</param>
/// <returns></returns>
private byte[] getImageByteData(Bitmap source, int thumbWi, int thumbHi, bool maintainAspect)
{
byte[] ret = null;
//调用创建缩略图,根据源图创建一张指定大小的缩略图
Bitmap thumbnail = CreateThumbnail(source, thumbWi, thumbHi, maintainAspect);
#region 配置JPEG压缩引餐,可压缩90%以上,质量与原图相当
//配置压缩缩略图所需encoderParameters 参数
EncoderParameters encoderParams = new EncoderParameters();
long[] quality = new long[1];
quality[0] = 75;//压缩质量,范围0~100,压缩质量与大小成反比
EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
encoderParams.Param[0] = encoderParam;
//获取图像编码器对象数组
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegICI = null;
//编码对象数组里获取JPEG的编码信息
for (int x = 0; x < arrayICI.Length; x++)
{
if (arrayICI[x].FormatDescription.Equals("JPEG"))
{
jpegICI = arrayICI[x];
break;
}
}
#endregion
MemoryStream ms = new MemoryStream();
//使用指定JPEG参数,保存到内存流
thumbnail.Save(ms, jpegICI, encoderParams);
ret = ms.ToArray();
thumbnail.Dispose();
return ret;
}
/// <summary>
/// 创建缩略图
/// </summary>
/// <param name="source">源图</param>
/// <param name="thumbWi">缩略图宽度</param>
/// <param name="thumbHi">缩略图高度</param>
/// <param name="maintainAspect">是否保持长宽比例</param>
/// <returns></returns>
private Bitmap CreateThumbnail(Bitmap source, int thumbWi, int thumbHi, bool maintainAspect)
{
// 如果源图高度宽度小过缩略的高度宽度,则直接返回源图
if (source.Width <= thumbWi && source.Height <= thumbHi) return source;
System.Drawing.Bitmap ret = null;
try
{
int wi, hi;
wi = thumbWi;
hi = thumbHi;
if (maintainAspect)
{
//保持长宽比例,不管缩略图大小参数
if (source.Width > source.Height)
{
wi = thumbWi;
hi = (int)(source.Height * ((decimal)thumbWi / source.Width));
}
else
{
hi = thumbHi;
wi = (int)(source.Width * ((decimal)thumbHi / source.Height));
}
}
// original code that creates lousy thumbnails
// System.Drawing.Image ret = source.GetThumbnailImage(wi,hi,null,IntPtr.Zero);
ret = new Bitmap(wi, hi);
using (Graphics g = Graphics.FromImage(ret))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.FillRectangle(Brushes.White, 0, 0, wi, hi);
g.DrawImage(source, 0, 0, wi, hi);
}
}
catch
{
ret = null;
}
return ret;
}
/// <summary>
/// 使用.net自带的提取缩略图方法创建缩略图
/// </summary>
/// <param name="imageStream">图像输入流</param>
/// <param name="thumbWi">指定缩略图宽度</param>
/// <param name="thumbHi">指定缩略图高度</param>
/// <returns>返回缩略图字节数据</returns>
private byte[] getImageByteData(Stream imageStream, int thumbWi, int thumbHi)
{
System.Drawing.Image image = System.Drawing.Image.FromStream(imageStream);
int height = thumbHi;
int width = thumbWi;
if (image.Height > height || image.Width > width)
{
//变缩略图
System.Drawing.Image.GetThumbnailImageAbort callb = null;
//使用指定大小提取缩略图
System.Drawing.Image thumbnailImage = image.GetThumbnailImage(thumbWi, thumbHi, callb, new System.IntPtr());
image = thumbnailImage;
}
MemoryStream Stream = new MemoryStream();
image.Save(Stream, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] byteData = Stream.ToArray();
return byteData;
}
/// <summary>
/// 使用重绘方式创建缩略图
/// </summary>
/// <param name="source">源图</param>
/// <param name="thumbWi">指定缩略图宽度</param>
/// <param name="thumbHi">指定缩略图高度</param>
/// <param name="maintainAspect">是否保持长宽比例</param>
/// <returns></returns>
private byte[] getImageByteData(Bitmap source, int thumbWi, int thumbHi, bool maintainAspect)
{
byte[] ret = null;
//调用创建缩略图,根据源图创建一张指定大小的缩略图
Bitmap thumbnail = CreateThumbnail(source, thumbWi, thumbHi, maintainAspect);
#region 配置JPEG压缩引餐,可压缩90%以上,质量与原图相当
//配置压缩缩略图所需encoderParameters 参数
EncoderParameters encoderParams = new EncoderParameters();
long[] quality = new long[1];
quality[0] = 75;//压缩质量,范围0~100,压缩质量与大小成反比
EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
encoderParams.Param[0] = encoderParam;
//获取图像编码器对象数组
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegICI = null;
//编码对象数组里获取JPEG的编码信息
for (int x = 0; x < arrayICI.Length; x++)
{
if (arrayICI[x].FormatDescription.Equals("JPEG"))
{
jpegICI = arrayICI[x];
break;
}
}
#endregion
MemoryStream ms = new MemoryStream();
//使用指定JPEG参数,保存到内存流
thumbnail.Save(ms, jpegICI, encoderParams);
ret = ms.ToArray();
thumbnail.Dispose();
return ret;
}
/// <summary>
/// 创建缩略图
/// </summary>
/// <param name="source">源图</param>
/// <param name="thumbWi">缩略图宽度</param>
/// <param name="thumbHi">缩略图高度</param>
/// <param name="maintainAspect">是否保持长宽比例</param>
/// <returns></returns>
private Bitmap CreateThumbnail(Bitmap source, int thumbWi, int thumbHi, bool maintainAspect)
{
// 如果源图高度宽度小过缩略的高度宽度,则直接返回源图
if (source.Width <= thumbWi && source.Height <= thumbHi) return source;
System.Drawing.Bitmap ret = null;
try
{
int wi, hi;
wi = thumbWi;
hi = thumbHi;
if (maintainAspect)
{
//保持长宽比例,不管缩略图大小参数
if (source.Width > source.Height)
{
wi = thumbWi;
hi = (int)(source.Height * ((decimal)thumbWi / source.Width));
}
else
{
hi = thumbHi;
wi = (int)(source.Width * ((decimal)thumbHi / source.Height));
}
}
// original code that creates lousy thumbnails
// System.Drawing.Image ret = source.GetThumbnailImage(wi,hi,null,IntPtr.Zero);
ret = new Bitmap(wi, hi);
using (Graphics g = Graphics.FromImage(ret))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.FillRectangle(Brushes.White, 0, 0, wi, hi);
g.DrawImage(source, 0, 0, wi, hi);
}
}
catch
{
ret = null;
}
return ret;
}