Asp.net mvc實(shí)時(shí)生成縮率圖到硬盤

字號(hào):


    這篇文章主要介紹了Asp.net mvc實(shí)時(shí)生成縮率圖到硬盤的相關(guān)資料,需要的朋友可以參考下
    對(duì)于縮率圖的處理是在圖片上傳到服務(wù)器之后,同步生成兩張不同尺寸的縮率供前端調(diào)用,剛開(kāi)始還能滿足需求,慢慢的隨著前端展示的多樣化,縮率圖已不能前端展示的需求,所以考慮做一個(gè)實(shí)時(shí)生成圖片縮率圖服務(wù)。
    每次調(diào)用實(shí)時(shí)生成縮率圖,不緩存著實(shí)有點(diǎn)浪費(fèi),所以在生成縮率的同時(shí)緩存到硬盤一份,效率提高很多。
    之前從網(wǎng)上看了一下有人用nginx + lua實(shí)現(xiàn)的,效率那是沒(méi)什么可說(shuō)的,但是時(shí)間緊迫,自己也沒(méi)時(shí)間去研究,所以暫時(shí)先用aps.net mvc4來(lái)實(shí)現(xiàn) 一個(gè),以后有時(shí)間了,再慢慢修改。
    用自己熟悉的.net性能可能差那么一點(diǎn)點(diǎn),但是實(shí)現(xiàn)速度快,保證可以在極端的時(shí)間內(nèi)上線,并且在功能上更強(qiáng)。
    思路很簡(jiǎn)單,就是根據(jù)請(qǐng)求,判斷需要的縮率圖是否已存在于硬盤上,如果有直接返回,沒(méi)有則下載原圖,并生成縮率圖到本地,返回給客戶端。
    下面直接粘貼代碼片段:
    /// <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對(duì)應(yīng)字典
    /// </summary>
    static Dictionary<string, string> extensionContentTypeDic;
    static FileHelper()
    {
     if (extensionContentTypeDic == null)
     {
     //.jpg", ".png", ".gif", ".jpeg
     extensionContentTypeDic = 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>
    /// 根據(jù)后綴名獲取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對(duì)象轉(zhuǎn)化成二進(jìn)制流 
    /// </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> 
    /// 字節(jié)流轉(zhuǎn)換成圖片 
    /// </summary> 
    /// <param name="byt">要轉(zhuǎn)換的字節(jié)流</param> 
    /// <returns>轉(zhuǎn)換得到的Image對(duì)象</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;
     }
     //新建一個(gè)bmp圖片 
     System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
     //新建一個(gè)畫板 
     Graphics g = System.Drawing.Graphics.FromImage(bitmap);
     //設(shè)置高質(zhì)量插值法 
     g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
     //設(shè)置高質(zhì)量,低速度呈現(xiàn)平滑程度 
     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,
    }
    訪問(wèn)方式:
    http://www.souji8.com/Home/Index/{width}_{height}_{ThumMode}?p={imageUrl}
    {imageUrl}:目標(biāo)圖片地址
    {ThumMode}: 1:指定高寬按比例、2:指定寬,高按比例、3:指定高寬裁減(不變形)
    {Width}:期望圖片寬
    {Height}:期望圖片高
    以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。