Asp.net mvc 实时生成缩率图到硬盘
之前对于缩率图的处理是在图片上传到服务器之后,同步生成两张不同尺寸的缩率供前端调用,刚开始还能满足需求,慢慢的随着前端展示的多样化,缩率图已不能前端展示的需求,所以考虑做一个实时生成图片缩率图服务。
每次调用实时生成缩率图,不缓存着实有点浪费,所以在生成缩率的同时缓存到硬盘一份,效率提高很多。
之前从网上看了一下有人用nginx + lua实现的,效率那是没什么可说的,但是时间紧迫,自己也没时间去研究,所以暂时先用aps.net mvc4来实现 一个,以后有时间了,再慢慢修改。
用自己熟悉的.net性能可能差那么一点点,但是实现速度快,保证可以在极端的时间内上线,并且在功能上更强。
思路很简单,就是根据请求,判断需要的缩率图是否已存在于硬盘上,如果有直接返回,没有则下载原图,并生成缩率图到本地,返回给客户端。
下面直接粘贴代码片段:
/// <summary>
/// 生成图片缩率图Action
/// </summary>
/// <param name="p">原图url</param>
/// <param name="id">图片尺寸以及生成缩率图的类型</param>
/// <returns></returns>
[HttpGet]
public async Task<ActionResult> Index(string p, string id)
{
if (string.IsNullOrEmpty(p))
{
return new HttpStatusCodeResult();
} string oPath = Regex.Replace(p, @"http[s]?://(.*?)/", "/", RegexOptions.IgnoreCase);
int? oWidth = , oHeight = ;
int cutMode = ;
string pPath;
string oDir; if (!string.IsNullOrEmpty(id))
{
string[] ss = id.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
if (ss.Length < )
{
return new HttpStatusCodeResult();
}
if (ss.Length > )
{
cutMode = int.Parse(ss[]);
}
oPath = oPath.Insert(oPath.LastIndexOf('/') + , string.Format("{0}_{1}_{2}_", ss[], ss[], cutMode));
oWidth = int.Parse(ss[]);
oHeight = int.Parse(ss[]);
} pPath = Server.MapPath(oPath);
oDir = Path.GetDirectoryName(pPath); if (!System.IO.File.Exists(pPath))
{
byte[] imagebytes =await FileHelper.DownLoadFileAsync(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(, , 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 = ;
int y = ;
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 = ;
x = (originalImage.Width - ow) / ;
}
else
{
ow = originalImage.Width;
oh = originalImage.Width * height / towidth;
x = ;
y = (originalImage.Height - oh) / ;
}
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(, , 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 Task<byte[]> DownLoadFileAsync(string remoteUrl)
{
WebClient wc = new WebClient();
try
{
return wc.DownloadDataTaskAsync(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}:期望图片高
等有时间了,再改成nginx+lua 实现。
Asp.net mvc 实时生成缩率图到硬盘的更多相关文章
- Asp.Net MVC路由生成URL过程
这次谈一谈Asp.Net MVC中所学到的路由生成URL的相关技术,顺便提一提遇到的一些坑,真的是掉坑掉多了,也就习以为常了,大不了从坑里再爬出来.初学者,包括我,都以为,mvc的核心是模型视图控制器 ...
- ASP.NET MVC动态生成网站菜单及子菜单
在开发ASP.NET MVC网站时,Insus.NET想实现动态产生网站的主菜单及子菜单. 你需要在网站管理后台管理此2张表(Menu,SubMenu)的信息,添加,删除,编辑,更新等. Sequen ...
- thinkphp3.2.3----图片上传并生成缩率图
public function uploadify(){ if(!IS_POST){ $this->error('非法!'); } $upload = $this->_upload(); ...
- asp.net mvc + javascript生成下载文件
近期做的是对现有项目进行重构.WEB FROM改成MVC,其实也算是推倒重来了. 里面有一个导出功能,将数据输出成txt文件,供下载.原先的做法是有一个隐藏的iframe,在这个iframe的页面中设 ...
- asp.net mvc NPOI 生成Excel文件
private string PushToDown(string addtime) { DataTable dt = _bCreateCode.PushtoExcel(addtime); //1.实例 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章 ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架 ...
- 学习ASP.NET MVC(五)——我的第一个ASP.NET MVC CURD页面
在上一篇文章中我们已经创建了实体类,在这一篇文章中,我将创建一个新的控制器类——BookController,使用BookController对Books表中的数据进行CURD操作的方法,并使用视图模 ...
- ASP.NET MVC学习笔记(二)笔记
接下来我们一起了解ASP.NET MVC的最重要的核心技术,了解ASP.NET MVC的开发框架,生命周期,技术细节. 一.Routing与ASP.NET MVC生命周期 1.Routing——网址路 ...
- ASP.NET MVC 重命名[命名空间]而导致的错误及发现的ASP.NET MVC Bug一枚
使用VS2012新建了一个Asp.net mvc5的项目,并把项目的命名空间名称更改了(Src更改为UXXXXX),然后就导致了以下错误 刚开始以后是项目的属性中的命名空间没有更改过来的问题,但我在重 ...
随机推荐
- Docker Swarm 服务编排之命令
一.简介 Docker有个编排工具docker-compose,可以将组成某个应该的多个docker容器编排在一起,同时管理.同样在Swarm集群中,可以使用docker stack 将一组相关联的服 ...
- KVM基本实现原理
KVM 虚拟化技术概述 http://blog.csdn.net/yearn520/article/details/6461047 KVM 虚拟化技术在 AMD 平台上的实现 1.http://www ...
- zkw费用流模板
理论:http://www.cnblogs.com/acha/p/6735037.html #include<cstdio> #include<cstring> #includ ...
- 2017 国庆湖南 Day1
卡特兰数 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ] ...
- github pages 正确访问方式
❌ http://username.github.io ✅ http://username.github.io. github pages 绑定域名后,由于浏览器dns缓存,需要重启一下
- 详细讲解安全升级MySQL的方法
MySQL升级是非常必要的. 我们在Percona Support上列出了关于MySQL升级最佳实践的各种问题.这篇文章推荐了一些不同情况下升级MySQL的方法. 为什么MySQL升级是必须的? 原因 ...
- 20155213 2016-2017-2 《Java程序设计》第七周学习总结
20155213 2016-2017-2 <Java程序设计>第七周学习总结 教材学习内容总结 Lambda 如果使用JDK8的话,可以使用Lambda特性去除重复的信息. 在只有Lamb ...
- Linux的基础优化
归结成口诀: 一清.一精.一增.两优.四设.七其他 一清: 定时清理日志 一精: 精简开机启动服务 一增: 增大文件描述符 两优: linux内核参数的优化.yum源优化 四设:设置系统的字符集.设置 ...
- torch.nn.CrossEntropyLoss
class torch.nn.CrossEntropyLoss(weight=None, size_average=True, ignore_index=-100, reduce=True) 我这里没 ...
- 【Git】Git与GitHub 入门【转】
转自:http://www.cnblogs.com/lcw/p/3394545.html GitHub GitHub是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公 ...