/// <summary> /// 生成缩略图(选择Cute可保证图片不变形) /// </summary> /// <param name="fileStream">源图流</param> /// <param name="width">缩略图宽度</param> /// <param name="height">缩略图高度</param> /// <param name="bgColor">缩略图背景填充色</param> /// <param name="mode">根据枚举类型确定压缩策略</param> public static Stream MakeThumbnail(Stream fileStream, int width, int height, Color bgColor, ImageThumbStrategy mode) { if (null == fileStream) { return(null); } Stream ms = null; Image originalImage = Image.FromStream(fileStream); int towidth = width; //指定的缩略图的宽度 int toheight = height; //指定缩略图的高度 int drawX = 0; //指定在新的画布上开始画图的左顶点左边X int drawY = 0; //指定在新的画布上开始画图的左顶点左边Y int drawW = width; //指定在画布中需要画的宽度 int drawH = height; //指定在画布中需要画的高度 int cuteX = 0; //在源图上进行截图的坐标X int cuteY = 0; //在源图上进行截图的坐标Y int cuteW = originalImage.Width; //在源图上进行截图的宽度 int cuteH = originalImage.Height; //在源图上进行截图的高度 Image ThumbImage = null; switch (mode) { case ImageThumbStrategy.Cut: #region 指定高宽裁减(不变形) if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight) { cuteH = originalImage.Height; cuteW = originalImage.Height * towidth / toheight; cuteY = 0; cuteX = (originalImage.Width - cuteW) / 2; } else { cuteW = originalImage.Width; cuteH = originalImage.Width * toheight / towidth; cuteX = 0; cuteY = (originalImage.Height - cuteH) / 2; } break; #endregion case ImageThumbStrategy.SmartCut: //智能裁剪,小图周围填充色 #region 智能裁剪,取短板压缩到指定,长版从中间截取,都小则使用填充色 /* * 缩略图的宽与高都比源图大,执行将源图放在新的图片的正中间策略 */ if (originalImage.Width <= width && originalImage.Height <= height) { //图中图的左顶点坐标 drawX = (width - originalImage.Width) / 2; drawY = (height - originalImage.Height) / 2; drawW = originalImage.Width; drawH = originalImage.Height; } else { if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight) { cuteH = originalImage.Height; cuteW = originalImage.Height * towidth / toheight; cuteY = 0; cuteX = (originalImage.Width - cuteW) / 2; } else { cuteW = originalImage.Width; cuteH = originalImage.Width * toheight / towidth; cuteX = 0; cuteY = (originalImage.Height - cuteH) / 2; } } break; #endregion case ImageThumbStrategy.SmartFill: //智能填充,小图周围填充色 #region 智能裁剪,取长板压缩到指定,短版居中绘制,都小则使用填充色(只是复制了 尚未开发 研究中) /* * 缩略图的宽与高都比源图大,执行将源图放在新的图片的正中间策略 */ if (originalImage.Width <= width && originalImage.Height <= height) { #region 宽高均小,居中 四周填充 //如果源图宽和高都小于指定压缩的图片的宽高,将源图置于画布中间,四周填充色 drawX = (width - originalImage.Width) / 2; drawY = (height - originalImage.Height) / 2; drawW = originalImage.Width; drawH = originalImage.Height; //指定源图截取部分为全图 cuteW = originalImage.Width; cuteH = originalImage.Height; cuteX = 0; cuteY = 0; #endregion } else { double origRate_wh = (double)originalImage.Width / (double)originalImage.Height; double toRate_Wh = (double)towidth / (double)toheight; if (origRate_wh > toRate_Wh) { #region 宽度进行等比缩放到指定压缩宽度 int thumb_w = towidth; int thumb_h = (int)((double)originalImage.Height * (double)towidth / (double)originalImage.Width); ThumbImage = originalImage.GetThumbnailImage(thumb_w, thumb_h, ThumbnailCallback, IntPtr.Zero); //指定源图在画布中所要展示的左定点位置与大小(计算居中坐标) drawW = ThumbImage.Width; drawH = ThumbImage.Height; drawX = 0; drawY = Math.Abs(toheight - ThumbImage.Height) / 2; //指定源图截取部分为全图 cuteW = ThumbImage.Width; cuteH = ThumbImage.Height; cuteX = 0; cuteY = 0; #endregion } else { #region 高度进行等比缩放到指定压缩高度 int thumb_w = (int)((double)originalImage.Width * (double)toheight / (double)originalImage.Height); int thumb_h = toheight; ThumbImage = originalImage.GetThumbnailImage(thumb_w, thumb_h, ThumbnailCallback, IntPtr.Zero); //指定源图在画布中所要展示的左定点位置与大小(计算居中坐标) drawW = ThumbImage.Width; drawH = ThumbImage.Height; drawX = Math.Abs(towidth - ThumbImage.Width) / 2; drawY = 0; //指定源图截取部分为全图 cuteW = ThumbImage.Width; cuteH = ThumbImage.Height; cuteX = 0; cuteY = 0; #endregion } } break; #endregion case ImageThumbStrategy.Width: //指定宽,高按比例 #region 指定宽,高按比例 toheight = originalImage.Height * width / originalImage.Width; drawH = toheight; break; #endregion case ImageThumbStrategy.Height: //指定高,宽按比例 #region 指定高,宽按比例 towidth = originalImage.Width * height / originalImage.Height; drawW = towidth; break; #endregion default: break; } //新建一个bmp图片 Bitmap b = new Bitmap(towidth, toheight); try { //新建一个画板 Graphics g = Graphics.FromImage(b); //设置高质量插值法 g.InterpolationMode = InterpolationMode.HighQualityBicubic; //设置高质量,低速度呈现平滑程度 g.SmoothingMode = SmoothingMode.AntiAlias; g.PixelOffsetMode = PixelOffsetMode.HighQuality; //清空画布并以透明背景色填充 g.Clear(bgColor); if (null != ThumbImage) { //在指定位置并且按指定大小绘制原图片的指定部分 g.DrawImage( ThumbImage, //要绘制的源图 new Rectangle(drawX, drawY, drawW, drawH), //指定源图所在画布的位置与大小 new Rectangle(cuteX, cuteY, cuteW, cuteH), //指定需要绘制源图中的部分 GraphicsUnit.Pixel ); ImageFormat actFormat = GetFormat(originalImage.RawFormat.Guid); if (null == actFormat) { throw new Exception("图片格式异常"); } ImageCodecInfo ici = GetCodecInfo("image/" + actFormat.ToString().ToLower()); ms = SaveImage(b, ici); ms.Position = 0; } else { //在指定位置并且按指定大小绘制原图片的指定部分 g.DrawImage( originalImage, //要绘制的源图 new Rectangle(drawX, drawY, drawW, drawH), //指定源图所在画布的位置与大小 new Rectangle(cuteX, cuteY, cuteW, cuteH), //指定需要绘制源图中的部分 GraphicsUnit.Pixel ); ImageFormat actFormat = GetFormat(originalImage.RawFormat.Guid); if (null == actFormat) { throw new Exception("图片格式异常"); } ImageCodecInfo ici = GetCodecInfo("image/" + actFormat.ToString().ToLower()); ms = SaveImage(b, ici); ms.Position = 0; } } catch (System.Exception e) { throw e; } finally { if (null != ThumbImage) { ThumbImage.Dispose(); } originalImage.Dispose(); b.Dispose(); fileStream.Seek(0, SeekOrigin.Begin); } return(ms); }
/// <summary> /// 生成缩略图(选择Cute可保证图片不变形) /// </summary> /// <param name="fileStream">源图流</param> /// <param name="width">缩略图宽度</param> /// <param name="height">缩略图高度</param> /// <param name="mode">根据枚举类型确定压缩策略</param> public static Stream MakeThumbnail(Stream fileStream, int width, int height, ImageThumbStrategy mode) { return(MakeThumbnail(fileStream, width, height, Color.Transparent, mode)); }