Welcome 微信登录

首页 / 网页编程 / ASP.NET / Asp.net mvc实时生成缩率图到硬盘

对于缩率图的处理是在图片上传到服务器之后,同步生成两张不同尺寸的缩率供前端调用,刚开始还能满足需求,慢慢的随着前端展示的多样化,缩率图已不能前端展示的需求,所以考虑做一个实时生成图片缩率图服务。

每次调用实时生成缩率图,不缓存着实有点浪费,所以在生成缩率的同时缓存到硬盘一份,效率提高很多。

之前从网上看了一下有人用nginx + lua实现的,效率那是没什么可说的,但是时间紧迫,自己也没时间去研究,所以暂时先用aps.net mvc4来实现 一个,以后有时间了,再慢慢修改。

用自己熟悉的.net性能可能差那么一点点,但是实现速度快,保证可以在极端的时间内上线,并且在功能上更强。

思路很简单,就是根据请求,判断需要的缩率图是否已存在于硬盘上,如果有直接返回,没有则下载原图,并生成缩率图到本地,返回给客户端。

下面直接粘贴代码片段:

/// <summary> /// 生成图片缩率图Action /// </summary> /// <param name="p">原图url</param> /// <param name="id">图片尺寸以及生成缩率图的类型</param> /// <returns></returns> [ValidateInput(false)] public ActionResult Index(string p, string id) {if (string.IsNullOrEmpty(p)){return new HttpStatusCodeResult(404);}string oPath = Regex.Replace(p, @"http[s]?://(.*?)/", "/", RegexOptions.IgnoreCase);int? oWidth = 200, oHeight = 200;int cutMode = 3;string pPath;string oDir;if (!string.IsNullOrEmpty(id)){string[] ss = id.Split(new char[] { "_" }, StringSplitOptions.RemoveEmptyEntries);if (ss.Length < 2){ return new HttpStatusCodeResult(404);}if (ss.Length > 2){ cutMode = int.Parse(ss[2]);}oPath = oPath.Insert(oPath.LastIndexOf("/") + 1, string.Format("{0}_{1}_{2}_", ss[0], ss[1], cutMode));oWidth = int.Parse(ss[0]);oHeight = int.Parse(ss[1]);}pPath = Server.MapPath(oPath);oDir = Path.GetDirectoryName(pPath);if (!System.IO.File.Exists(pPath)){byte[] imagebytes = FileHelper.DownLoadFile(p);if (!Directory.Exists(oDir)){ Directory.CreateDirectory(oDir);}FileHelper.MakeThumbnail(FileHelper.BytToImg(imagebytes), oWidth.Value, oHeight.Value, (ThumbnailMode)cutMode, pPath, true);}return File(pPath, FileHelper.GetContentTypeByExtension(Path.GetExtension(pPath).ToLower())); }

辅助方法:

 public class FileHelper {/// <summary> /// 图片后缀和ContentType对应字典 /// </summary> static Dictionary<string, string> extensionContentTypeDic; static FileHelper() {if (extensionContentTypeDic == null){//.jpg", ".png", ".gif", ".jpegextensionContentTypeDic = new Dictionary<string, string>();extensionContentTypeDic.Add(".jpg", "image/jpeg");extensionContentTypeDic.Add(".png", "image/png");extensionContentTypeDic.Add(".gif", "image/gif");extensionContentTypeDic.Add(".jpeg", "image/jpeg");} } /// <summary> /// 根据后缀名获取extension /// </summary> /// <param name="extension"></param> /// <returns></returns> public static string GetContentTypeByExtension(string extension) {if (extensionContentTypeDic.ContainsKey(extension)){return extensionContentTypeDic[extension];}return null; } /// <summary >/// 将Image对象转化成二进制流/// </summary >/// <param name="image" > </param >/// <returns > </returns >public static byte[] ImageToByteArray(Image image) {MemoryStream imageStream = new MemoryStream();Bitmap bmp = new Bitmap(image.Width, image.Height);Graphics g = Graphics.FromImage(bmp);g.DrawImage(image, new System.Drawing.Rectangle(0, 0, image.Width, image.Height));try{bmp.Save(imageStream, image.RawFormat);}catch (Exception e){bmp.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);}byte[] byteImg = imageStream.GetBuffer();bmp.Dispose();g.Dispose();imageStream.Close();return byteImg; } /// <summary>/// 字节流转换成图片/// </summary>/// <param name="byt">要转换的字节流</param>/// <returns>转换得到的Image对象</returns>public static Image BytToImg(byte[] byt) {MemoryStream ms = new MemoryStream(byt);Image img = Image.FromStream(ms);ms.Close();return img; } /// <summary> /// 生成缩率图 /// </summary> /// <param name="originalImage">原始图片Image</param> /// <param name="width">缩率图宽</param> /// <param name="height">缩率图高</param> /// <param name="mode">生成缩率图的方式</param> /// <param name="thumbnailPath">缩率图存放的地址</param> public static Image MakeThumbnail(Image originalImage, int width, int height, ThumbnailMode mode, string thumbnailPath, bool isSave = true) {int towidth = width;int toheight = height;int x = 0;int y = 0;int ow = originalImage.Width;int oh = originalImage.Height;switch (mode){case ThumbnailMode.HW://指定高宽缩放(可能变形)break;case ThumbnailMode.W://指定宽,高按比例toheight = originalImage.Height * width / originalImage.Width; break;case ThumbnailMode.H://指定高,宽按比例towidth = originalImage.Width * height / originalImage.Height; break;case ThumbnailMode.Cut://指定高宽裁减(不变形)if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight) { oh = originalImage.Height; ow = originalImage.Height * towidth / toheight; y = 0; x = (originalImage.Width - ow) / 2; } else { ow = originalImage.Width; oh = originalImage.Width * height / towidth; x = 0; y = (originalImage.Height - oh) / 2; } break;default: break;}//新建一个bmp图片 System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);//新建一个画板 Graphics g = System.Drawing.Graphics.FromImage(bitmap);//设置高质量插值法 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;//设置高质量,低速度呈现平滑程度 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//清空画布并以透明背景色填充 g.Clear(Color.Transparent);//在指定位置并且按指定大小绘制原图片的指定部分 g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),new Rectangle(x, y, ow, oh),GraphicsUnit.Pixel);if (!isSave){return bitmap;}try{//以jpg格式保存缩略图 //bitmap.Save(thumbnailPath, bitmap.RawFormat);bitmap.Save(thumbnailPath, ImageFormat.Jpeg);return bitmap;}catch (System.Exception e){throw e;}finally{originalImage.Dispose();bitmap.Dispose();g.Dispose();}return null; } /// <summary> /// 下载指定文件 /// </summary> /// <param name="remoteUrl"></param> /// <param name="ss"></param> public static byte[] DownLoadFile(string remoteUrl) {WebClient wc = new WebClient();try{return wc.DownloadData(remoteUrl);}catch (Exception e){throw new Exception("下载文件失败");} } } public enum ThumbnailMode { /// <summary> /// 指定高宽缩放(可能变形) /// </summary> HW, /// <summary> /// 指定高,宽按比例 /// </summary> H, /// <summary> /// 指定宽,高按比例 /// </summary> W, /// <summary> /// 指定高宽裁减(不变形)/// </summary> Cut, }
 

访问方式:

http://www.souji8.com/Home/Index/{width}_{height}_{ThumMode}?p={imageUrl}

{imageUrl}:目标图片地址

{ThumMode}: 1:指定高宽按比例、2:指定宽,高按比例、3:指定高宽裁减(不变形)

{Width}:期望图片宽

{Height}:期望图片高

以上就是本文的全部内容,希望对大家的学习有所帮助。