Asp.net mvc實(shí)時(shí)生成縮率圖到硬盤
對(duì)于縮率圖的處理是在圖片上傳到服務(wù)器之后,同步生成兩張不同尺寸的縮率供前端調(diào)用,剛開始還能滿足需求,慢慢的隨著前端展示的多樣化,縮率圖已不能前端展示的需求,所以考慮做一個(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í)有所幫助。
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之文件夾實(shí)現(xiàn)
- asp.net 網(wǎng)絡(luò)硬盤實(shí)現(xiàn)分析
- ASP.NET+XML打造網(wǎng)絡(luò)硬盤原理分析
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之兩重要類代碼
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之查看文件夾實(shí)現(xiàn)代碼
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之上傳文件實(shí)現(xiàn)代碼
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之下載或在線查看實(shí)現(xiàn)代碼
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之刪除文件夾實(shí)現(xiàn)代碼
相關(guān)文章
詳解ASP.NET?Core高性能服務(wù)器HTTP.SYS
HTTP.SYS本質(zhì)上就是一個(gè)HTTP/HTTPS監(jiān)聽器,它是Windows網(wǎng)絡(luò)子系統(tǒng)的一部分,是一個(gè)在內(nèi)核模式下運(yùn)行的網(wǎng)絡(luò)驅(qū)動(dòng),今天通過(guò)本文給大家介紹下ASP.NET?Core高性能服務(wù)器HTTP.SYS,感興趣的朋友一起看看吧2022-04-04asp.net使用Socket.Send發(fā)送信息及Socket.SendFile傳輸文件的方法
這篇文章主要介紹了asp.net使用Socket.Send發(fā)送信息及Socket.SendFile傳輸文件的方法,結(jié)合實(shí)例形式分析了asp.net基于socket實(shí)現(xiàn)信息與文件傳輸?shù)南嚓P(guān)技巧,需要的朋友可以參考下2016-06-06asp.net中的GridView分頁(yè)問(wèn)題
這篇文章主要介紹了asp.net中的GridView分頁(yè)問(wèn)題,實(shí)例講述了采用GridView分頁(yè)出現(xiàn)的問(wèn)題及對(duì)應(yīng)的解決方案,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-11-11ASP.NET筆記之Session、http、web開發(fā)原則、xss漏洞的詳細(xì)介紹
本篇文章小編為大家介紹,ASP.NET筆記之Session、http、web開發(fā)原則、xss漏洞詳細(xì)。需要的朋友參考下2013-04-04詳解ASP.NET 生成二維碼實(shí)例(采用ThoughtWorks.QRCode和QrCode.Net兩種方式)
本篇文章主要介紹了ASP.NET 生成二維碼實(shí)例,使用了兩種方法,包括ThoughtWorks.QRCode和QrCode.Net,具有一定的參考價(jià)值,有興趣的可以了解一下。2016-12-12asp.net 無(wú)法獲取的內(nèi)部?jī)?nèi)容,因?yàn)樵搩?nèi)容不是文本 的解決方法
asp.net 無(wú)法獲取的內(nèi)部?jī)?nèi)容,因?yàn)樵搩?nèi)容不是文本 的解決方法2009-12-12解析WPF實(shí)現(xiàn)音頻文件循環(huán)順序播放的解決方法
本篇文章是對(duì)WPF實(shí)現(xiàn)音頻文件循環(huán)順序播放的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05詳解最好的.NET開源免費(fèi)ZIP庫(kù)DotNetZip(.NET組件介紹之三)
本篇文章主要介紹了.NET開源免費(fèi)ZIP庫(kù)DotNetZip組件的介紹,可以實(shí)現(xiàn)對(duì)文件的壓縮和解壓,有興趣的朋友可以了解一下。2016-12-12Rx.NET庫(kù)中IDisposable對(duì)象的用法
這篇文章介紹了Rx.NET庫(kù)中IDisposable對(duì)象的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07微信公眾平臺(tái)開發(fā)之發(fā)送文本消息.Net代碼解析
這篇文章主要為大家詳細(xì)解析了微信公眾平臺(tái)開發(fā)之發(fā)送文本消息.Net代碼,感興趣的小伙伴們可以參考一下2016-06-06