C#的另类图片缩放

导读:在指定大小的框框内,对图片等比例缩放,你有没有碰到?有的话以下代码可能有些用。


问题场景

最近碰到一个客户提出一个需求:图片缩放功能,上传的图片尺寸可以是任何比例,而且有横向也有纵向的,在规定的尺寸范围内缩放,缩放后的图片不能有剪切的,缩放后图片可视比例和原图片比例相等。如果明白的话,很明显这种缩放,横向或纵向可能会留空白的边,于是把这种情况跟客户说了,客户也很明白,说可以接受。


问题分析得出思路

平时接触的图片缩放或剪切,都不是此类的,先在google上搜索了一下,有需求,但没有看到几个解决方案,这么来真的要自己写一些程序了,缕缕思路:首先要计算出缩放后图片的尺寸,该尺寸的长宽都在指定尺寸范围内,也就是,如果上传的图片和指定尺寸比例不等的话,不是纵向就是横向会留下空边,但不会两向都会留,因为上传的图片长宽都比指定尺寸大的话,需要把图片缩小,直至长或宽和指定的长或宽相等,如果上传的图片长宽都比指定的长宽小的话,也需要把图片放大,直至长或宽和指定的长或宽相等。开始写代码了,先把这个思想转化成代码:

  1. /// <summary>  
  2. /// 给定一个矩形(长方形 正方形)剪切的范围 传入一张图片的原始尺寸   
  3. /// 得到一个在该矩形范围内的最佳尺寸(原图的比例不会变)  
  4. /// add 2goo 2011-4-8  
  5. /// </summary>  
  6. /// <param name="specifySize">指定尺寸</param>  
  7. /// <param name="originalSize">原始尺寸</param>  
  8. /// <returns>返回(原图片等比例)最佳尺寸</returns>  
  9. private static Size ResizeSite(Size specifySize, Size originalSize)  
  10. {  
  11.     Size finaSize = new Size();  
  12.     float specifyScale = (float)specifySize.Width / (float)specifySize.Height;  
  13.     float originalScale = (float)originalSize.Width / (float)originalSize.Height;  
  14.     if (specifySize.Width >= originalSize.Width)  
  15.     {  
  16.         finaSize.Height = specifySize.Height;  
  17.         finaSize.Width = (int)(finaSize.Height * originalScale);  
  18.         if (finaSize.Width > specifySize.Width)  
  19.         {  
  20.             finaSize.Width = specifySize.Width;  
  21.             finaSize.Height = (int)(finaSize.Width / originalScale);  
  22.         }  
  23.     }  
  24.     else  
  25.     {  
  26.         finaSize.Width = specifySize.Width;  
  27.         finaSize.Height = (int)(finaSize.Width / originalScale);  
  28.         if (finaSize.Height > specifySize.Height)  
  29.         {  
  30.             finaSize.Height = specifySize.Height;  
  31.             finaSize.Width = (int)(finaSize.Height * originalScale);  
  32.         }  
  33.     }  
  34.     return finaSize;  
  35. }  


后续思路

只要结合指定尺寸把上传的图片的长宽计算出来,那剩下的工作就是图片的缩放处理了,写代码之前,想法大概思路是这样的:先结合刚才的代码,把图片的长宽取出来,用C#的Graphics DrawImage把图片等比列缩放成计算出来的尺寸,然后再画个新图,尺寸和指向尺寸一样,把刚才的缩放好的图片粘贴找这张新图上即可,当然这个过程,还要计算空边(有两边)的尺寸,好了写好代码如下:

  1. /// <summary>  
  2. /// 缩放图片 按比例 如果指定的尺寸和原图片尺寸比例不等,会留空边  
  3. /// 2goo add 2011-04-06  
  4. /// </summary>  
  5. /// <param name="postedFile">原图HttpPostedFile对象</param>  
  6. /// <param name="savePath">保存图片的绝对路径 包括图片名</param>  
  7. /// <param name="newWidth">指定宽度</param>  
  8. /// <param name="newHeight">指定高度</param>  
  9. public static void ResizeImage(System.Web.HttpPostedFile postedFile,   
  10.     string savePath, int newWidth, int newHeight)  
  11. {  
  12.     //创建目录  
  13.     string dir = Path.GetDirectoryName(savePath);  
  14.     if (!Directory.Exists(dir))  
  15.         Directory.CreateDirectory(dir);  
  16.   
  17.     //原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息)  
  18.     System.Drawing.Image originalImage =   
  19.         System.Drawing.Image.FromStream(postedFile.InputStream, true);  
  20.   
  21.     int ow = originalImage.Width;//原始宽度  
  22.     int oh = originalImage.Height;//原始高度  
  23.   
  24.     Size toSize = ResizeSite(new Size(newWidth, newHeight), new Size(ow,oh));  
  25.     int towidth = toSize.Width;//原图片缩放后的宽度  
  26.     int toheight = toSize.Height;//原图片缩放后的高度  
  27.   
  28.     int x = 0;  
  29.     int y = 0;  
  30.   
  31.     x = (newWidth - towidth) / 2;  
  32.     y = (newHeight - toheight) / 2;  
  33.   
  34.     //新建一个bmp图片  
  35.     System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);  
  36.     //新建一个画板  
  37.     System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);  
  38.     //设置高质量插值法  
  39.     g.InterpolationMode =  
  40.         System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;  
  41.     //设置高质量,低速度呈现平滑程度  
  42.     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;  
  43.     //清空画布并以透明背景色填充  
  44.     g.Clear(System.Drawing.Color.Transparent);  
  45.     //在指定位置并且按指定大小绘制原图片的指定部分  
  46.     g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight),  
  47.     new System.Drawing.Rectangle(0, 0, ow, oh),  
  48.     System.Drawing.GraphicsUnit.Pixel);  
  49.     //--------------------------------------------------------------------------------  
  50.   
  51.     //新建一个bmp图片2  
  52.     System.Drawing.Image bitmap2 = new System.Drawing.Bitmap(newWidth, newHeight);  
  53.     //新建一个画板2  
  54.     System.Drawing.Graphics g2 = System.Drawing.Graphics.FromImage(bitmap2);  
  55.     //设置高质量插值法  
  56.     g2.InterpolationMode =   
  57.         System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;  
  58.     //设置高质量,低速度呈现平滑程度  
  59.     g2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;  
  60.     //清空画布并以透明背景色填充  
  61.     g2.Clear(System.Drawing.Color.White);  
  62.     g2.DrawImageUnscaled(bitmap,new Point(x,y));  
  63.   
  64.     try  
  65.     {  
  66.         //以jpg格式保存缩略图  
  67.         bitmap2.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);  
  68.     }  
  69.     catch (System.Exception e)  
  70.     {  
  71.         throw e;  
  72.     }  
  73.     finally  
  74.     {  
  75.         originalImage.Dispose();  
  76.         bitmap.Dispose();  
  77.         bitmap2.Dispose();  
  78.         g2.Dispose();  
  79.         g.Dispose();  
  80.     }  
  81. }  

其中有到的类库如下:

  1. using System;  
  2. using System.Drawing;  
  3. using System.IO;  

如果有问题,回复我...http://2goo.info/blog/panjj/other/2011/04/08/513

posted @ 2011-04-09 08:58 2goO 阅读(...) 评论(...) 编辑 收藏