之前对于缩率图的处理是在图片上传到服务器之后,同步生成两张不同尺寸的缩率供前端调用,刚开始还能满足需求,慢慢的随着前端展示的多样化,缩率图已不能前端展示的需求,所以考虑做一个实时生成图片缩率图服务。

每次调用实时生成缩率图,不缓存着实有点浪费,所以在生成缩率的同时缓存到硬盘一份,效率提高很多。

之前从网上看了一下有人用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 实时生成缩率图到硬盘的更多相关文章

  1. Asp.Net MVC路由生成URL过程

    这次谈一谈Asp.Net MVC中所学到的路由生成URL的相关技术,顺便提一提遇到的一些坑,真的是掉坑掉多了,也就习以为常了,大不了从坑里再爬出来.初学者,包括我,都以为,mvc的核心是模型视图控制器 ...

  2. ASP.NET MVC动态生成网站菜单及子菜单

    在开发ASP.NET MVC网站时,Insus.NET想实现动态产生网站的主菜单及子菜单. 你需要在网站管理后台管理此2张表(Menu,SubMenu)的信息,添加,删除,编辑,更新等. Sequen ...

  3. thinkphp3.2.3----图片上传并生成缩率图

    public function uploadify(){ if(!IS_POST){ $this->error('非法!'); } $upload = $this->_upload(); ...

  4. asp.net mvc + javascript生成下载文件

    近期做的是对现有项目进行重构.WEB FROM改成MVC,其实也算是推倒重来了. 里面有一个导出功能,将数据输出成txt文件,供下载.原先的做法是有一个隐藏的iframe,在这个iframe的页面中设 ...

  5. asp.net mvc NPOI 生成Excel文件

    private string PushToDown(string addtime) { DataTable dt = _bCreateCode.PushtoExcel(addtime); //1.实例 ...

  6. 《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架 ...

  7. 学习ASP.NET MVC(五)——我的第一个ASP.NET MVC CURD页面

    在上一篇文章中我们已经创建了实体类,在这一篇文章中,我将创建一个新的控制器类——BookController,使用BookController对Books表中的数据进行CURD操作的方法,并使用视图模 ...

  8. ASP.NET MVC学习笔记(二)笔记

    接下来我们一起了解ASP.NET MVC的最重要的核心技术,了解ASP.NET MVC的开发框架,生命周期,技术细节. 一.Routing与ASP.NET MVC生命周期 1.Routing——网址路 ...

  9. ASP.NET MVC 重命名[命名空间]而导致的错误及发现的ASP.NET MVC Bug一枚

    使用VS2012新建了一个Asp.net mvc5的项目,并把项目的命名空间名称更改了(Src更改为UXXXXX),然后就导致了以下错误 刚开始以后是项目的属性中的命名空间没有更改过来的问题,但我在重 ...

随机推荐

  1. python3.5中import sqlite3报错:ImportError: No module named _sqlite3

    原因:缺少相关库 解决方案: 1  安装相关库 yum install sqlite-devel 2  重新编译安装Python

  2. P4888 三去矩阵

    P4888 三去矩阵 给出一个字符矩阵, 多次询问求以 \((x, y)\) 为中心的最长回文串长度(即横竖两种) \(l, q <= 2000\) Solution 数据范围小直接模拟即可 C ...

  3. Dubbo学习笔记1:使用Zookeeper搭建服务治理中心

    Zookeeper是Apache Hadoop的子项目,是一个树形的目录服务,支持变更推送,适合作为Dubbo服务的注册中心,工业强度较高,推荐生成环境使用. , 下面结合上图介绍Zookeeper在 ...

  4. 用Python来进行词频统计

    # 把语料中的单词全部抽取出来, 转成小写, 并且去除单词中间的特殊符号 def words(text): return re.findall('[a-z]+', text.lower()) def ...

  5. Jenkins git 的配置及问题解决

    背景:最近项目需要 Jenkins 集成git,着手记录遇到的问题及解决方式 一.搭建Jenkins环境步骤这里(略) 二.安装Jenkins插件(系统管理-->插件管理-->可选插件)选 ...

  6. SpringCloud微服务简介(一)

    Spring Cloud简单认识 微服务英文名称Microservice,Microservice架构模式就是将整个Web应用组织为一系列小的Web服务.这些小的Web服务可以独立地编译及部署,并通过 ...

  7. 20155303 2016-2017-2 《Java程序设计》第七周学习总结

    20155303 2016-2017-2 <Java程序设计>第七周学习总结 教材学习中的问题和解决过程 『问题一』:SimpleDateFormat中每个字符的含义都是什么? 『问题一解 ...

  8. Tetrahedron(Codeforces Round #113 (Div. 2) + 打表找规律 + dp计数)

    题目链接: https://codeforces.com/contest/166/problem/E 题目: 题意: 给你一个三菱锥,初始时你在D点,然后你每次可以往相邻的顶点移动,问你第n步回到D点 ...

  9. POJ 3255 Roadblocks (次短路 SPFA )

    题目链接 Description Bessie has moved to a small farm and sometimes enjoys returning to visit one of her ...

  10. HDU 1073 Online Judge (字符串处理)

    题目链接 Problem Description Ignatius is building an Online Judge, now he has worked out all the problem ...