Asp.net mvc实时生成缩率图到硬盘
对于缩率图的处理是在图片上传到服务器之后,同步生成两张不同尺寸的缩率供前端调用,刚开始还能满足需求,慢慢的随着前端展示的多样化,缩率图已不能前端展示的需求,所以考虑做一个实时生成图片缩率图服务。
每次调用实时生成缩率图,不缓存着实有点浪费,所以在生成缩率的同时缓存到硬盘一份,效率提高很多。
之前从网上看了一下有人用nginx+lua实现的,效率那是没什么可说的,但是时间紧迫,自己也没时间去研究,所以暂时先用aps.netmvc4来实现一个,以后有时间了,再慢慢修改。
用自己熟悉的.net性能可能差那么一点点,但是实现速度快,保证可以在极端的时间内上线,并且在功能上更强。
思路很简单,就是根据请求,判断需要的缩率图是否已存在于硬盘上,如果有直接返回,没有则下载原图,并生成缩率图到本地,返回给客户端。
下面直接粘贴代码片段:
///<summary> ///生成图片缩率图Action ///</summary> ///<paramname="p">原图url</param> ///<paramname="id">图片尺寸以及生成缩率图的类型</param> ///<returns></returns> [ValidateInput(false)] publicActionResultIndex(stringp,stringid) { if(string.IsNullOrEmpty(p)) { returnnewHttpStatusCodeResult(404); } stringoPath=Regex.Replace(p,@"http[s]?://(.*?)/","/",RegexOptions.IgnoreCase); int?oWidth=200,oHeight=200; intcutMode=3; stringpPath; stringoDir; if(!string.IsNullOrEmpty(id)) { string[]ss=id.Split(newchar[]{'_'},StringSplitOptions.RemoveEmptyEntries); if(ss.Length<2) { returnnewHttpStatusCodeResult(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); } returnFile(pPath,FileHelper.GetContentTypeByExtension(Path.GetExtension(pPath).ToLower())); }
辅助方法:
publicclassFileHelper { ///<summary> ///图片后缀和ContentType对应字典 ///</summary> staticDictionary<string,string>extensionContentTypeDic; staticFileHelper() { if(extensionContentTypeDic==null) { //.jpg",".png",".gif",".jpeg extensionContentTypeDic=newDictionary<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> ///<paramname="extension"></param> ///<returns></returns> publicstaticstringGetContentTypeByExtension(stringextension) { if(extensionContentTypeDic.ContainsKey(extension)) { returnextensionContentTypeDic[extension]; } returnnull; } ///<summary> ///将Image对象转化成二进制流 ///</summary> ///<paramname="image"></param> ///<returns></returns> publicstaticbyte[]ImageToByteArray(Imageimage) { MemoryStreamimageStream=newMemoryStream(); Bitmapbmp=newBitmap(image.Width,image.Height); Graphicsg=Graphics.FromImage(bmp); g.DrawImage(image,newSystem.Drawing.Rectangle(0,0,image.Width,image.Height)); try { bmp.Save(imageStream,image.RawFormat); } catch(Exceptione) { bmp.Save(imageStream,System.Drawing.Imaging.ImageFormat.Jpeg); } byte[]byteImg=imageStream.GetBuffer(); bmp.Dispose(); g.Dispose(); imageStream.Close(); returnbyteImg; } ///<summary> ///字节流转换成图片 ///</summary> ///<paramname="byt">要转换的字节流</param> ///<returns>转换得到的Image对象</returns> publicstaticImageBytToImg(byte[]byt) { MemoryStreamms=newMemoryStream(byt); Imageimg=Image.FromStream(ms); ms.Close(); returnimg; } ///<summary> ///生成缩率图 ///</summary> ///<paramname="originalImage">原始图片Image</param> ///<paramname="width">缩率图宽</param> ///<paramname="height">缩率图高</param> ///<paramname="mode">生成缩率图的方式</param> ///<paramname="thumbnailPath">缩率图存放的地址</param> publicstaticImageMakeThumbnail(ImageoriginalImage,intwidth,intheight,ThumbnailModemode,stringthumbnailPath,boolisSave=true) { inttowidth=width; inttoheight=height; intx=0; inty=0; intow=originalImage.Width; intoh=originalImage.Height; switch(mode) { caseThumbnailMode.HW://指定高宽缩放(可能变形) break; caseThumbnailMode.W://指定宽,高按比例 toheight=originalImage.Height*width/originalImage.Width; break; caseThumbnailMode.H://指定高,宽按比例 towidth=originalImage.Width*height/originalImage.Height; break; caseThumbnailMode.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.Imagebitmap=newSystem.Drawing.Bitmap(towidth,toheight); //新建一个画板 Graphicsg=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,newRectangle(0,0,towidth,toheight), newRectangle(x,y,ow,oh), GraphicsUnit.Pixel); if(!isSave) { returnbitmap; } try { //以jpg格式保存缩略图 //bitmap.Save(thumbnailPath,bitmap.RawFormat); bitmap.Save(thumbnailPath,ImageFormat.Jpeg); returnbitmap; } catch(System.Exceptione) { throwe; } finally { originalImage.Dispose(); bitmap.Dispose(); g.Dispose(); } returnnull; } ///<summary> ///下载指定文件 ///</summary> ///<paramname="remoteUrl"></param> ///<paramname="ss"></param> publicstaticbyte[]DownLoadFile(stringremoteUrl) { WebClientwc=newWebClient(); try { returnwc.DownloadData(remoteUrl); } catch(Exceptione) { thrownewException("下载文件失败"); } } } publicenumThumbnailMode { ///<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}:期望图片高
以上就是本文的全部内容,希望对大家的学习有所帮助。