• 生成缩略图时报GDI+中发生一般性错误


    最近由于业务需要要写一个生成缩略图并能设置图片质量的功能,本来这是一件so easy的事,以前也干过,可是却遇到了问题。话不多说先看代码

        /// <summary>
        /// 等比生成缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径(物理路径)</param>
        /// <param name="thumbnailPath">缩略图路径(物理路径)</param>
        /// <param name="width">缩略图最大宽度</param>
        /// <param name="height">缩略图最大高度</param>
        /// <param name="imageQualityValue">图片要保存的压缩质量,该参数的值为1至100的整数,数值越大,保存质量越好</param>
        public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, int imageQualityValue)
        {
            //原图名称
            string imgName = originalImagePath.Substring(originalImagePath.LastIndexOf("\") + 1);
            //根目录
            string path1 = System.Web.HttpContext.Current.Server.MapPath("~/Upload/");
            //将原图移动到根目录下
            File.Move(originalImagePath, path1 + imgName);
            //获取移动后的原图路径
            string newpath = path1 + imgName;
            //读取图片信息
            System.Drawing.Image originalImage = System.Drawing.Image.FromFile(newpath);
            #region 获取缩略图宽高
            int w = 0;//最终缩略图的宽
            int h = 0;//最终缩略图的高
            if (originalImage.Width > width && originalImage.Height < height)
            {
                w = width;
                h = width * originalImage.Height / originalImage.Width;
            }
            else if (originalImage.Width < width && originalImage.Height > height)
            {
                h = height;
                w = height * originalImage.Width / originalImage.Height;
            }
            else if (originalImage.Width > width && originalImage.Height > height)
            {
                if ((double)originalImage.Width / (double)originalImage.Height > (double)width / (double)height)
                {//如果原图的宽高比 > 缩略图的宽高比  宽缩放
                    w = width;
                    h = width * originalImage.Height / originalImage.Width;
                }
                else
                {//如果原图的宽高比 <= 缩略图的宽高比  高缩放
                    h = height;
                    w = originalImage.Width * h / originalImage.Height;
                }
            }
            #endregion
            if (w == 0 || h == 0)
            {
                return;
            }
      //新建一个bmp图片
            System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
    
            //新建一个画板
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
    
            //设置高质量插值法
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
    
            //设置高质量,低速度呈现平滑程度
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    
            //清空画布并以透明背景色填充
            g.Clear(System.Drawing.Color.Transparent);
    
            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight), new System.Drawing.Rectangle(x, y, ow, oh), System.Drawing.GraphicsUnit.Pixel);
    
            //以下代码为保存图片时,设置压缩质量
            EncoderParameters encoderParameters = new EncoderParameters();
            EncoderParameter encoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100);
            encoderParameters.Param[0] = encoderParameter;
    
            ImageCodecInfo[] ImageCodecInfoArray = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo jpegImageCodecInfo = null;
            for (int i = 0; i < ImageCodecInfoArray.Length; i++)
            {
                if (ImageCodecInfoArray[i].FormatDescription.Equals("PNG"))
                {
                    jpegImageCodecInfo = ImageCodecInfoArray[i];
                    break;
                }
            }
    
            try
            {
                bitmap.Save(thumbnailPath, jpegImageCodecInfo, encoderParameters);
            }
            catch (System.Exception e)
            {
                throw e;
            }
            finally
            {
                encoderParameters.Dispose();
                encoderParameter.Dispose();
                originalImage.Dispose();
                bitmap.Dispose();
                g.Dispose();
                File.Delete(path1 + imgName);
            }
            GC.Collect();
        }

      乍一看,代码没有如何问题,那就运行起来吧

    TMD竟然报错了,什么原因呢,然后就摆渡了,网上各种方法各种试,都不好使!猫了眯的,怎么回事?最后开始问朋友,朋友也没辙,而且我写的方法在他那不报错,神了。难道老天针对我!神经病啊,不对,再问朋友的过程中朋友一句话点醒了我,你为什么要移动图片啊!哦哦哦,这才想起来这个方法一些没用,后来改了一次就是为了让他报错的,然后我就屁颠屁颠的去掉了最开始的那几行移动图片的代码,不出意外的通过了,运行良好。感谢天感谢地终于写好了,修改过后的代码如下

     1     /// <summary>
     2     /// 等比生成缩略图
     3     /// </summary>
     4     /// <param name="originalImagePath">源图路径(物理路径)</param>
     5     /// <param name="thumbnailPath">缩略图路径(物理路径)</param>
     6     /// <param name="width">缩略图最大宽度</param>
     7     /// <param name="height">缩略图最大高度</param>
     8     /// <param name="imageQualityValue">图片要保存的压缩质量,该参数的值为1至100的整数,数值越大,保存质量越好</param>
     9     public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, int imageQualityValue)
    10     {
    11         //原图名称
    12         //读取图片信息
    13         System.Drawing.Image originalImage = System.Drawing.Image.FromFile(originalImagePath);
    14         #region 获取缩略图宽高
    15         int w = 0;//最终缩略图的宽
    16         int h = 0;//最终缩略图的高
    17         if (originalImage.Width > width && originalImage.Height < height)
    18         {
    19             w = width;
    20             h = width * originalImage.Height / originalImage.Width;
    21         }
    22         else if (originalImage.Width < width && originalImage.Height > height)
    23         {
    24             h = height;
    25             w = height * originalImage.Width / originalImage.Height;
    26         }
    27         else if (originalImage.Width > width && originalImage.Height > height)
    28         {
    29             if ((double)originalImage.Width / (double)originalImage.Height > (double)width / (double)height)
    30             {//如果原图的宽高比 > 缩略图的宽高比  宽缩放
    31                 w = width;
    32                 h = width * originalImage.Height / originalImage.Width;
    33             }
    34             else
    35             {//如果原图的宽高比 <= 缩略图的宽高比  高缩放
    36                 h = height;
    37                 w = originalImage.Width * h / originalImage.Height;
    38             }
    39         }
    40         #endregion
    41         if (w == 0 || h == 0)
    42         {
    43             return;
    44         }
    45         //新建一个bmp图片
    46         System.Drawing.Image bitmap = new System.Drawing.Bitmap(w, h);
    47         //获取高清的Graphics
    48         System.Drawing.Graphics g = GetGraphics(bitmap);
    49         //清空画布并以透明背景色填充
    50         g.Clear(System.Drawing.Color.Transparent);
    51         //在指定位置并且按指定大小绘制原图片的指定部分
    52         g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, w, h), new System.Drawing.Rectangle(0, 0, originalImage.Width, originalImage.Height), System.Drawing.GraphicsUnit.Pixel);
    53         if (originalImagePath == thumbnailPath)
    54         {
    55             originalImage.Dispose();
    56         }
    57         //保存到文件,同时进一步控制质量
    58         SaveImage2File(thumbnailPath, bitmap, imageQualityValue);
    59 
    60         //bitmap.Save(thumbnailPath, jpegImageCodecInfo, encoderParameters);
    61         if (originalImage != null)
    62         {
    63             originalImage.Dispose();
    64         }
    65         bitmap.Dispose();
    66         g.Dispose();
    67         GC.Collect();
    68     }
     1   /// <summary>
     2     /// 将Image实例保存到文件,注意此方法不执行 img.Dispose()
     3     /// 图片保存时本可以直接使用destImage.Save(path, ImageFormat.Jpeg),但是这种方法无法进行进一步控制图片质量
     4     /// </summary>
     5     /// <param name="path"></param>
     6     /// <param name="img"></param>
     7     /// <param name="quality">1~100整数,无效值,则取默认值95</param>
     8     /// <param name="mimeType"></param>
     9     public static void SaveImage2File(string path, Image destImage, int quality, string mimeType = "image/jpeg")
    10     {
    11         if (quality <= 0 || quality > 100) quality = 95;
    12         //创建保存的文件夹
    13         FileInfo fileInfo = new FileInfo(path);
    14         if (!Directory.Exists(fileInfo.DirectoryName))
    15         {
    16             Directory.CreateDirectory(fileInfo.DirectoryName);
    17         }
    18         //设置保存参数,保存参数里进一步控制质量
    19         EncoderParameters encoderParams = new EncoderParameters();
    20         long[] qua = new long[] { quality };
    21         EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
    22         encoderParams.Param[0] = encoderParam;
    23         //获取指定mimeType的mimeType的ImageCodecInfo
    24         var codecInfo = ImageCodecInfo.GetImageEncoders().FirstOrDefault(ici => ici.MimeType == mimeType);
    25         try
    26         {
    27             destImage.Save(path, codecInfo, encoderParams);
    28         }
    29         catch (Exception)
    30         {
    31             throw;
    32         }
    33         finally
    34         {
    35             fileInfo = null;
    36             encoderParams.Dispose();
    37             encoderParam.Dispose();
    38         }
    39     }
    40     /// <summary>
    41     /// 获取高清的Graphics
    42     /// </summary>
    43     /// <param name="img"></param>
    44     /// <returns></returns>
    45     public static Graphics GetGraphics(Image img)
    46     {
    47         var g = Graphics.FromImage(img);
    48         //设置质量
    49         g.SmoothingMode = SmoothingMode.HighQuality;
    50         g.CompositingQuality = CompositingQuality.HighQuality;
    51         //InterpolationMode不能使用High或者HighQualityBicubic,如果是灰色或者部分浅色的图像是会在边缘处出一白色透明的线
    52         //用HighQualityBilinear却会使图片比其他两种模式模糊(需要肉眼仔细对比才可以看出)
    53         g.InterpolationMode = InterpolationMode.Default;
    54         g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    55         return g;
    56     }

    真是有时候蠢起来连自己都怕

  • 相关阅读:
    python 字符串内建函数之开头与结尾判断
    python 字符串内建函数之查找、替换
    python 字符串内建函数之大小写
    python 字符串切片
    python for循环
    python if语句
    python input( )
    python 变量命名规则
    DllMain
    静态库lib和动态dll的区别及使用方法
  • 原文地址:https://www.cnblogs.com/zhhwDavidblog/p/7554292.html
Copyright © 2020-2023  润新知