导读:在指定大小的框框内,对图片等比例缩放,你有没有碰到?有的话以下代码可能有些用。
问题场景最近碰到一个客户提出一个需求:图片缩放功能,上传的图片尺寸可以是任何比例,而且有横向也有纵向的,在规定的尺寸范围内缩放,缩放后的图片不能有剪切的,缩放后图片可视比例和原图片比例相等。如果明白的话,很明显这种缩放,横向或纵向可能会留空白的边,于是把这种情况跟客户说了,客户也很明白,说可以接受。
问题分析得出思路
平时接触的图片缩放或剪切,都不是此类的,先在google上搜索了一下,有需求,但没有看到几个解决方案,这么来真的要自己写一些程序了,缕缕思路:首先要计算出缩放后图片的尺寸,该尺寸的长宽都在指定尺寸范围内,也就是,如果上传的图片和指定尺寸比例不等的话,不是纵向就是横向会留下空边,但不会两向都会留,因为上传的图片长宽都比指定尺寸大的话,需要把图片缩小,直至长或宽和指定的长或宽相等,如果上传的图片长宽都比指定的长宽小的话,也需要把图片放大,直至长或宽和指定的长或宽相等。开始写代码了,先把这个思想转化成代码:
/// <summary> /// 给定一个矩形(长方形 正方形)剪切的范围 传入一张图片的原始尺寸 /// 得到一个在该矩形范围内的最佳尺寸(原图的比例不会变) /// add 2goo 2011-4-8 /// </summary> /// <param name="specifySize">指定尺寸</param> /// <param name="originalSize">原始尺寸</param> /// <returns>返回(原图片等比例)最佳尺寸</returns> private static Size ResizeSite(Size specifySize, Size originalSize) { Size finaSize = new Size(); float specifyScale = (float)specifySize.Width / (float)specifySize.Height; float originalScale = (float)originalSize.Width / (float)originalSize.Height; if (specifySize.Width >= originalSize.Width) { finaSize.Height = specifySize.Height; finaSize.Width = (int)(finaSize.Height * originalScale); if (finaSize.Width > specifySize.Width) { finaSize.Width = specifySize.Width; finaSize.Height = (int)(finaSize.Width / originalScale); } } else { finaSize.Width = specifySize.Width; finaSize.Height = (int)(finaSize.Width / originalScale); if (finaSize.Height > specifySize.Height) { finaSize.Height = specifySize.Height; finaSize.Width = (int)(finaSize.Height * originalScale); } } return finaSize; }
后续思路
只要结合指定尺寸把上传的图片的长宽计算出来,那剩下的工作就是图片的缩放处理了,写代码之前,想法大概思路是这样的:先结合刚才的代码,把图片的长宽取出来,用C#的Graphics DrawImage把图片等比列缩放成计算出来的尺寸,然后再画个新图,尺寸和指向尺寸一样,把刚才的缩放好的图片粘贴找这张新图上即可,当然这个过程,还要计算空边(有两边)的尺寸,好了写好代码如下:
/// <summary> /// 缩放图片 按比例 如果指定的尺寸和原图片尺寸比例不等,会留空边 /// 2goo add 2011-04-06 /// </summary> /// <param name="postedFile">原图HttpPostedFile对象</param> /// <param name="savePath">保存图片的绝对路径 包括图片名</param> /// <param name="newWidth">指定宽度</param> /// <param name="newHeight">指定高度</param> public static void ResizeImage(System.Web.HttpPostedFile postedFile, string savePath, int newWidth, int newHeight) { //创建目录 string dir = Path.GetDirectoryName(savePath); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); //原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息) System.Drawing.Image originalImage = System.Drawing.Image.FromStream(postedFile.InputStream, true); int ow = originalImage.Width;//原始宽度 int oh = originalImage.Height;//原始高度 Size toSize = ResizeSite(new Size(newWidth, newHeight), new Size(ow,oh)); int towidth = toSize.Width;//原图片缩放后的宽度 int toheight = toSize.Height;//原图片缩放后的高度 int x = 0; int y = 0; x = (newWidth - towidth) / 2; y = (newHeight - toheight) / 2; //新建一个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.HighQualityBicubic; //设置高质量,低速度呈现平滑程度 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(0, 0, ow, oh), System.Drawing.GraphicsUnit.Pixel); //-------------------------------------------------------------------------------- //新建一个bmp图片2 System.Drawing.Image bitmap2 = new System.Drawing.Bitmap(newWidth, newHeight); //新建一个画板2 System.Drawing.Graphics g2 = System.Drawing.Graphics.FromImage(bitmap2); //设置高质量插值法 g2.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; //设置高质量,低速度呈现平滑程度 g2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; //清空画布并以透明背景色填充 g2.Clear(System.Drawing.Color.White); g2.DrawImageUnscaled(bitmap,new Point(x,y)); try { //以jpg格式保存缩略图 bitmap2.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg); } catch (System.Exception e) { throw e; } finally { originalImage.Dispose(); bitmap.Dispose(); bitmap2.Dispose(); g2.Dispose(); g.Dispose(); } }上面方法介绍:ResizeImage其实就是图片缩放,然后保存到磁盘里的整个过程。方法需要HttpPostedFile(Request.Files["controlName"]) 图片保存路径(绝对路径和包含图片的名字),保存宽度和高度。四个参数即可。
其中有到的类库如下:
using System; using System.Drawing; using System.IO;
如果有问题,回复我...