Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
 /// <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));
 }