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}:期望图片高
以上就是本文的全部内容,希望对大家的学习有所帮助。