Asp.net mvc实时生成缩率图到硬盘
程序员文章站
2023-12-14 15:43:58
对于缩率图的处理是在图片上传到服务器之后,同步生成两张不同尺寸的缩率供前端调用,刚开始还能满足需求,慢慢的随着前端展示的多样化,缩率图已不能前端展示的需求,所以考虑做一个实...
对于缩率图的处理是在图片上传到服务器之后,同步生成两张不同尺寸的缩率供前端调用,刚开始还能满足需求,慢慢的随着前端展示的多样化,缩率图已不能前端展示的需求,所以考虑做一个实时生成图片缩率图服务。
每次调用实时生成缩率图,不缓存着实有点浪费,所以在生成缩率的同时缓存到硬盘一份,效率提高很多。
之前从网上看了一下有人用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", ".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> /// 根据后缀名获取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}:期望图片高
以上就是本文的全部内容,希望对大家的学习有所帮助。