asp.net 动态压缩、切割图片,并做缓存处理机制
在asp.net中,新建一个handler,把需要切割的网内图片,通过调用此URL来切割并缓存。http://localhost:53829/CacheImage/ResizeImage.ashx?src=/Image/FolderLevel1\FolderLevel11\FolderLevel111/548974833.jpg&width=928&height=828&type=10&quality=90
注意:
1. width 和height至少有一个不为空
2. type默认为20,具体解释为:10-按宽度缩放不切高度;11-按宽度缩放切高度;20-按高度缩放不切宽度;21-按高度缩放切宽度;30-等比例缩略,高或宽不足比例补空白,不拉伸;31-拉伸原图缩略(会失真)
3. type为11,21的未实现,感觉用处不大
4.quality为压缩比率,默认为80
我的实例如下:
1.在网站根目录创建CacheImage文件夹,handler和所有的缓存文件都将存在个目录下,并按照源图片的结构缓存
2.再此文件夹下创建图片压缩处理的handler:ResizeImage.ashx
3.把CacheImage文件夹设为不需要登录权限即可访问,在web.config中配置
<location path="CacheImage">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
4.IIS中设置CacheImage的权限为可控
5.直接上Handler代码:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Configuration;
using log4net; namespace Alan.Web.CacheImage
{
/// <summary>
/// 动态缩略图处理程序
/// 调用示例: <img runat="server" src="~/CacheImage/ResizeImage.ashx?src=/Image/FolderLevel1/FolderLevel11/FolderLevel111/1299906975tusPd7.jpg&width=128&height=128&type=20&quality=90" />
/// type介绍:10-按宽度缩放不切高度;11-按宽度缩放切高度;20-按高度缩放不切宽度;21-按高度缩放切宽度;30-等比例缩略,高或宽不足比例补空白,不拉伸;31-拉伸原图缩略(会失真)
/// </summary>
public class ResizeImage : IHttpHandler
{
private ILog _log = LogManager.GetLogger(typeof (ResizeImage)); public void ProcessRequest(HttpContext context)
{
Stream fileStream = null;
try
{
context.Response.ContentType = "text/plain";
string fileName = context.Server.UrlDecode(context.Request["src"]);
string fileNameString = fileName; if (string.IsNullOrEmpty(fileName))
{
context.Response.Write("缺少参数src.");
return;
} //本地的图片则以/开头
if (fileName.StartsWith("/"))
{
fileName = System.Web.HttpContext.Current.Server.MapPath("~" + fileName);
} FileInfo fi = new FileInfo(fileName);
if (!fi.Exists)
{
context.Response.Write("图片不存在,文件名为:" + fileName);
return;
} Image image = Image.FromFile(fi.FullName);
int sourceWidth = image.Width, sourceHeight = image.Height;
if (sourceWidth == 0 || sourceHeight == 0)
{
context.Response.Write("错误:原始图片高度或宽度为0");
return;
} string widthStr = context.Request["width"];
string heightStr = context.Request["height"];
string typeStr = context.Request["type"];
string qualityStr = context.Request["quality"];
int deliveredWidth = 0, deliveredHeight = 0, type = 20;
long quality = 80;//图片质量默认为80 int.TryParse(widthStr, out deliveredWidth);
int.TryParse(heightStr, out deliveredHeight);
int.TryParse(typeStr, out type);
long.TryParse(qualityStr, out quality); string contentType = getContentType(fi.Extension);
context.Response.ContentType = contentType; //缓存图片的路径及格式:websiteurl+/CacheImage/FileName.type.deliveredHeight.deliveredWidth.quality.扩展名。(FileName包含文件夹路径)
string finallyFileName = System.AppDomain.CurrentDomain.BaseDirectory + "CacheImage/" + fileNameString +
"." + type + "." +
deliveredHeight + "." + deliveredWidth + "." + quality + fi.Extension; //如果缓存中有照片,从缓存中读取图片信息
if (File.Exists(finallyFileName))
{
try
{
using (Bitmap imagelocal = new Bitmap(finallyFileName))
{
using (MemoryStream ms = new MemoryStream())
{
imagelocal.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
context.Response.OutputStream.Write(ms.GetBuffer(), 0, (int) ms.Length);
}
}
return;
}
catch (Exception eee)
{
//若发生异常,删除此文件,继续生成新文件的操作
File.Delete(finallyFileName);
_log.Error(eee);
}
} try
{
int finallyWidth = 0, finallyHeight = 0;
string errorMessage = string.Empty; //如果计算失败,返回错误及原因,比如以高度作为依据却把高度设为0等
if (!ComputeWidthAndHeight(sourceWidth, sourceHeight, deliveredWidth, deliveredHeight, type,
ref finallyWidth, ref finallyHeight, ref errorMessage))
{
context.Response.Write(errorMessage);
return;
} //只有在源图片大于压缩图片的前提下才会压缩,否则直接返回源图片
if (sourceWidth > deliveredWidth || sourceHeight > deliveredHeight)
{
Bitmap bitmap = new Bitmap(finallyWidth, finallyHeight, PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.Clear(Color.White);
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; //平滑处理
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
//缩放质量
graphics.DrawImage(image, new Rectangle(0, 0, finallyWidth, finallyHeight));
image.Dispose();
EncoderParameters parameters = new EncoderParameters(1); parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality); //图片质量参数 //创建缓存所需的文件夹位置
int lastFolderIndex =
finallyFileName.LastIndexOf("/", StringComparison.CurrentCultureIgnoreCase) >
finallyFileName.LastIndexOf(@"\", StringComparison.CurrentCultureIgnoreCase)
? finallyFileName.LastIndexOf("/", StringComparison.CurrentCultureIgnoreCase)
: finallyFileName.LastIndexOf(@"\", StringComparison.CurrentCultureIgnoreCase);
string finallyFileFolder = finallyFileName.Substring(0,lastFolderIndex);
//若不存在缓存文件夹,创建文件夹目录
if (!Directory.Exists(finallyFileFolder))
{
Directory.CreateDirectory(finallyFileFolder);
}
fileStream = new FileStream(finallyFileName, FileMode.Create);
if (finallyFileName.ToLower().EndsWith(".bmp"))
{
bitmap.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png); //仅做图片裁切,不做压缩使用
}
else
{
bitmap.Save(fileStream, GetImageCodecInfo(contentType), parameters);
//用做图片质量压缩使用,通过parameters设置压缩比率,当压缩bmp图片时报错
} using (MemoryStream ms = new MemoryStream())
{
if (finallyFileName.ToLower().EndsWith(".bmp"))
{
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); //仅做图片裁切,不做压缩使用
}
else
{
bitmap.Save(ms, GetImageCodecInfo(contentType), parameters);
//用做图片质量压缩使用,通过parameters设置压缩比率,当压缩bmp图片时报错
} context.Response.OutputStream.Write(ms.GetBuffer(), 0, (int) ms.Length);
} parameters.Dispose();
bitmap.Dispose();
return;
} image.Dispose();
}
catch (Exception eexx)
{
//压缩文件失败,则继续下面返回原始图片的操作
_log.Error(eexx);
} //若上述有错或其他原因,返回源图片
fileStream = new FileStream(fi.FullName, FileMode.Open);
byte[] bytes = new byte[(int) fileStream.Length];
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Close();
context.Response.BinaryWrite(bytes); }
catch (Exception ex)
{
_log.Error(ex);
context.Response.Write(ex.Message);
}
finally
{
if (fileStream != null)
{
fileStream.Close();
fileStream.Dispose();
}
}
System.GC.Collect();
} /// <summary>
/// 获取文件下载类型
/// </summary>
/// <param name="extension"></param>
/// <returns></returns>
private string getContentType(string extension)
{
string ct = string.Empty;
switch (extension.ToLower())
{
case ".jpg":
ct = "image/jpeg";
break;
case ".png":
ct = "image/png";
break;
case ".gif":
ct = "image/gif";
break;
case ".bmp":
ct = "application/x-bmp";
break;
default:
ct = "image/jpeg";
break;
}
return ct;
} //获得包含有关内置图像编码解&码&器的信息的ImageCodecInfo 对象.
private ImageCodecInfo GetImageCodecInfo(string contentType)
{
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegICI = null;
for (int x = 0; x < arrayICI.Length; x++)
{
if (arrayICI[x].MimeType.Equals(contentType))
{
jpegICI = arrayICI[x];
//设置JPEG编码
break;
}
}
return jpegICI;
} /// <summary>
/// 计算压缩后图片的宽度和高度
/// </summary>
/// <param name="sourceWidth">源图片宽度</param>
/// <param name="sourceHeight"></param>
/// <param name="deliveredWidth">传递来的图片宽度</param>
/// <param name="deliveredHeight"></param>
/// <param name="type">type介绍:10-按宽度缩放不切高度;11-按宽度缩放切高度;20-按高度缩放不切宽度;21-按高度缩放切宽度;30-等比例缩略,高或宽不足比例补空白,不拉伸;31-拉伸原图缩略(会失真)</param>
/// <param name="finallyWidth"></param>
/// <param name="finallyHeight"></param>
/// <param name="errorMsg"></param>
/// <returns></returns>
private bool ComputeWidthAndHeight(int sourceWidth, int sourceHeight, int deliveredWidth, int deliveredHeight,int type, ref int finallyWidth, ref int finallyHeight, ref string errorMsg)
{
switch (type)
{
case 10:
{
if (deliveredWidth == 0)
{
errorMsg = "错误:缩放至目标的图片宽度为0";
return false;
}
finallyWidth = deliveredWidth;
finallyHeight = (int)(((double)deliveredWidth/sourceWidth)*sourceHeight);
}
break;
//case 11://TODO:11、12未做
// {
// if (deliveredWidth == 0)
// {
// errorMsg = "错误:缩放至目标的图片宽度为0";
// return false;
// }
// finallyWidth = deliveredWidth;
// finallyHeight = deliveredHeight;
// }
// break;
//case 21:
// {
// if (deliveredHeight == 0)
// {
// errorMsg = "错误:缩放至目标的图片高度为0";
// return false;
// }
// finallyWidth = sourceWidth;
// finallyHeight = deliveredHeight;
// }
// break;
case 30:
{
if(deliveredHeight==0||deliveredWidth==0)
{
errorMsg = "错误:缩放至目标的图片高度或宽度为0";
return false;
}
if (((double)sourceWidth / (double)sourceHeight) > ((double)deliveredWidth / (double)deliveredHeight))
{
//以宽度为基准缩小
if (sourceWidth > deliveredWidth)
{
finallyWidth = deliveredWidth;
finallyHeight = (int)(deliveredWidth * sourceHeight / (double)sourceWidth);
}
else
{
finallyWidth = sourceWidth;
finallyHeight = sourceHeight;
}
}
else
{
//以高度为基准缩小
if (sourceHeight > deliveredHeight)
{
finallyWidth = (int)(deliveredHeight * sourceWidth / (double)sourceHeight);
finallyHeight = deliveredHeight;
}
else
{
finallyWidth = sourceWidth;
finallyHeight = sourceHeight;
}
}
}
break;
case 31:
{
if (deliveredHeight == 0 || deliveredWidth == 0)
{
errorMsg = "错误:缩放至目标的图片高度或宽度为0";
return false;
}
finallyWidth = deliveredWidth;
finallyHeight = deliveredHeight;
}
break;
default://20
{
if (deliveredHeight == 0)
{
errorMsg = "错误:缩放至目标的图片高度为0";
return false;
}
finallyHeight = deliveredHeight;
finallyWidth = (int)((double)(deliveredHeight*sourceWidth)/sourceHeight);
}
break;
}
return true;
} public bool IsReusable
{
get { return false; }
}
}
}
6.调用代码如下:
<html>
<body>
<img height="128" width="80" src="http://admin.pl360.com/CacheImage/ResizeImage.ashx?src=/ShopData/ProductLogo/1465b59c-98f0-4c20-8002-996796db0d064.JPG&width=128&height=128&type=20&quality=90" />
</body>
</html>
asp.net 动态压缩、切割图片,并做缓存处理机制的更多相关文章
- 解决asp.net动态压缩
本来想写一个网站优化的系列(前端到后端的数据库,垂直优化到分布式,后面会补上),但没有时间(借口),今天就总结一下前几天优化网站的过程. 网站优化重点在于找出出现性能问题的地方,往往是解决方案很简单, ...
- asp.net动态输出透明gif图片
要使用asp.net动态输出透明gif图片,也就是用Response.ContentType = "image/GIF". 查了国内几个中文资料都没解决,最后是在一个英文博客上找到 ...
- Asp.Net静态资源动态压缩之WebOptimization
一.Asp.Net中对Css/Js的动态压缩工具 WebOptimization 在Asp.NetMVC自带的模板项目中自动引入了当前WebOptimization工具.如果使用的空模板Nuget命令 ...
- asp.net向后台传参数动态加载图片
//向后台传参数动态加载图片 $(function() { $("#Button1").click(function() { var stockcode = getUrlParam ...
- Android调用相册拍照控件实现系统控件缩放切割图片
android 下如果做处理图片的软件 可以调用系统的控件 实现缩放切割图片 非常好的效果 今天写了一个demo分享给大家 package cn.m15.test; import java.io.By ...
- Android 调用相册 拍照 实现系统控件缩放 切割图片
android 下如果做处理图片的软件 可以调用系统的控件 实现缩放切割图片 非常好的效果 今天写了一个demo分享给大家. package cn.m15.test; import java.io.B ...
- unity 内存中切割图片
一般的说我们切割图片是将一张图片资源切割成更小的图片资源,也就是说在资源上就进行了切割,比如ugui上的切割方法. 如果我们有一些情况比如做拼图,可能让玩家自己选择自己的生活照作为拼图的原图. 那么我 ...
- 两种方法实现用CSS切割图片只取图片中一部分
切割图片这里不是真正的切割,只是用CSS取图片中的一部分而已,主要有两种方式,一是做为某一元素的背景图片,二是用img元素的属性.下面有个不错的示例,大家可以参考下 切割图片这里不是真正的切割,只是用 ...
- 实现用CSS切割图片的方法
切割图片这里不是真正的切割,只是用CSS取图片中的一部分而已.这样做的好处就是减少了打开网页时请求图片的次数.主要有两种方式,一是做为某一元素的背景图片,二是用img元素的属性. 方法一: 用CSS中 ...
随机推荐
- [leetcode-606-Construct String from Binary Tree]
You need to construct a string consists of parenthesis and integers from a binary tree with the preo ...
- [leetcode-526-Beautiful Arrangement]
Suppose you have N integers from 1 to N. We define a beautiful arrangement as an array that is const ...
- 关闭chrome浏览器的developer tools
背景 Chrome使用过程中,很容易启动Chrome developer tools,一些误触如按到F12.CTRL+Shift+C等都会启动developer tools.对于不开发Web的人来说, ...
- 新技术探究之 GraphQL
What? GraphQL 是一种类似于 SQL 的结构化查询语言,由 facebook 于2012年创造,于2015年开源.SQL 在服务端定义,GraphQL 在客户端定义,也就是说 GraphQ ...
- Mongodb 参数说明及常见错误处理
在 CentOS7 上安装 MongoDB 1 通过 SecureCRT 连接至 CentOS7 服务器: 2 进入到 /usr/local/ 目录:cd /usr/local 3 在当前目录下 ...
- VB6之图像灰度与二值化
老代码备忘,我对图像处理不是太懂. 注:部分代码引援自网上,话说我到底自己写过什么代码... Private Declare Function GetBitmapBits Lib "gdi3 ...
- 基于GTID的Mysql-Mha高可用方案探索
声明: 本篇文章内容整理来源于互联网以及本人自己的梳理总结,目的是从零到一的搭建起来mysql mha高可用架构. 一.软件概述 MHA(Master High Availability)目前在MyS ...
- 单片机C语言基础编程源码六则2
1.某单片机系统的P2口接一数模转换器DAC0832输出模拟量,现在要求从DAC0832输出连续的三角波,实现的方法是从P2口连续输出按照三角波变化的数值,从0开始逐渐增大,到某一最大值后逐渐减小,直 ...
- Linux服务器下对Oracle作Rman备份
由于工作需要,最近要对几台Linux系统下的Oracle数据库进行Rman备份,就在操作的同时,整理了一下,方便今后作为资料进行查阅. ------------------------Linux服务器 ...
- C#获取当前时间详解
[转]C#获取当前日期时间(转) http://blog.163.com/ljq086@126/blog/static/549639712010112921658843/ 我们可以通过使用DataT ...