在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 动态压缩、切割图片,并做缓存处理机制的更多相关文章

  1. 解决asp.net动态压缩

    本来想写一个网站优化的系列(前端到后端的数据库,垂直优化到分布式,后面会补上),但没有时间(借口),今天就总结一下前几天优化网站的过程. 网站优化重点在于找出出现性能问题的地方,往往是解决方案很简单, ...

  2. asp.net动态输出透明gif图片

    要使用asp.net动态输出透明gif图片,也就是用Response.ContentType = "image/GIF". 查了国内几个中文资料都没解决,最后是在一个英文博客上找到 ...

  3. Asp.Net静态资源动态压缩之WebOptimization

    一.Asp.Net中对Css/Js的动态压缩工具 WebOptimization 在Asp.NetMVC自带的模板项目中自动引入了当前WebOptimization工具.如果使用的空模板Nuget命令 ...

  4. asp.net向后台传参数动态加载图片

    //向后台传参数动态加载图片 $(function() { $("#Button1").click(function() { var stockcode = getUrlParam ...

  5. Android调用相册拍照控件实现系统控件缩放切割图片

    android 下如果做处理图片的软件 可以调用系统的控件 实现缩放切割图片 非常好的效果 今天写了一个demo分享给大家 package cn.m15.test; import java.io.By ...

  6. Android 调用相册 拍照 实现系统控件缩放 切割图片

    android 下如果做处理图片的软件 可以调用系统的控件 实现缩放切割图片 非常好的效果 今天写了一个demo分享给大家. package cn.m15.test; import java.io.B ...

  7. unity 内存中切割图片

    一般的说我们切割图片是将一张图片资源切割成更小的图片资源,也就是说在资源上就进行了切割,比如ugui上的切割方法. 如果我们有一些情况比如做拼图,可能让玩家自己选择自己的生活照作为拼图的原图. 那么我 ...

  8. 两种方法实现用CSS切割图片只取图片中一部分

    切割图片这里不是真正的切割,只是用CSS取图片中的一部分而已,主要有两种方式,一是做为某一元素的背景图片,二是用img元素的属性.下面有个不错的示例,大家可以参考下 切割图片这里不是真正的切割,只是用 ...

  9. 实现用CSS切割图片的方法

    切割图片这里不是真正的切割,只是用CSS取图片中的一部分而已.这样做的好处就是减少了打开网页时请求图片的次数.主要有两种方式,一是做为某一元素的背景图片,二是用img元素的属性. 方法一: 用CSS中 ...

随机推荐

  1. fastJson将json字符串转换为map

    public class JsonUtil { /** * 将json转化成map * @param jsonStr * @return */ public static Map<String, ...

  2. CNN中的卷积核及TensorFlow中卷积的各种实现

    声明: 1. 我和每一个应该看这篇博文的人一样,都是初学者,都是小菜鸟,我发布博文只是希望加深学习印象并与大家讨论. 2. 我不确定的地方用了"应该"二字 首先,通俗说一下,CNN ...

  3. Log4Net不同日志类型写入到不同文件

    1. 一直在用log4net,从来没有自己整理过.实践出真知,只有自己整理过才能真正掌握. 2. log4net,应该读logfornet,以前一直说log4,log4............ 安装 ...

  4. Ext修改所有Ajax的timeout

    Ext修改所有Ajax的timeout stackoverflow上的解决方案 //需要在初始化viewport时执行 //方法一重写 Ext.Ajax.timeout= 60000; Ext.ove ...

  5. ASP.NET 导出EXCEL文件处理多对应排列的

    这次项目遇到了一个导出excel需要对应排列的问题.本来在做这个项目之前都基本没做过excel导出的菜鸡,这次强行做还是有些忐忑的,加上那个表的结构比较奇特.    废话不多说,先介绍表结构吧 是数据 ...

  6. EventUtil.addHandler方法

    EventUtil.addHandler: addHandler 方法,职责是分别视情况而定来使用DOM0级方法.DOM2级方法或IE方法来添加事件.   这个方法属于一个名字叫EventUtil的对 ...

  7. Django 踩过的坑(一)

    平台:win10 工具:cmd python3 刚刚学习Django搭建环境,网站还木有发布,就直接来了个大麻烦. 一切按着<Django 学习笔记(二)>这篇文章来的,在最后cmd运行服 ...

  8. VB6之切换桌面

    Desktop的API,用于切换或者系统桌面环境.扩展起来可以做一个锁屏程序或者多桌面程序. 模块部分: 'desktop.bas 'too much struct and declare unuse ...

  9. usaco training 4.1.3 fence6 题解

    Fence Loops题解 The fences that surround Farmer Brown's collection of pastures have gotten out of cont ...

  10. vijos1080题解

    题目: 对于一个递归函数w(a,b,c) 如果a<=0 or b<=0 or c<=0就返回值1. 如果a>20 or b>20 or c>20就返回w(20,20 ...