在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. java利用反射获取类的属性及类型

    java利用反射获取类的属性及类型. import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Map ...

  2. Flash TextField selectable bug block TextEvent.Link solution

    There is an old version Felx SDK bug(in my case it's Flex SDK v3.3.0.4852) that when TextField.selec ...

  3. Intellj IDEA光标为insert状态,无法删除内容

    以前用得是社区版的IDEA,今天装了14版本的,结果导入项目后,发现打开java文件的光标是win系统下按了insert键后的那种宽的光标,并且还无法删除内容,且按删除(delete)键也只见光标往前 ...

  4. php二进制流文件

    <?php $img_file = 'test.png'; // $fp = fopen($img_file, 'rb'); // $content = fread($fp, filesize( ...

  5. winform .net2.0的程序如何运行于.net 4.x

    约束 最近有一个winform项目,要求: (1)程序能够运行在winxp, win7, win8, win10中 (2)安装尽可能简单,尽量不要安装.net framework.即使要安装也要尽可以 ...

  6. 一个非常简单的例子告诉你attachEvent和addEventListener的区别

    <input id="test" type="button" value="测试"> <script> var te ...

  7. python编程快速上手之第3章实践项目参考答案

    1 #!/usr/bin/env python 2 # coding:utf-8 3 # write by mfyang 4 # collatz.py 5 # 从用户读入一个值,并判断这个值是不是一个 ...

  8. voa 2015.4.29

    Nepal has declared three days of mourning for the victims of Saturday's 7.8 magnitude earthquake tha ...

  9. 虚函数&多态

    对于经常被问到的虚函数和多态的问题,发现百度百科回答得十分详细,所以自己在百度百科上的解释进行总结 一.虚函数 (1)虚函数简介:在某基类中声明为virtual并在一个或者多个派生类中被重新定义的成员 ...

  10. Java探秘之神秘的字符串String(二)

    不可变性 String可以说是最常用的类型了,即字符串类型,String是常量(final关键词修饰的),他的值不能被创建后更改,因为字符串是不可被改变的,所以可以被用来共享. Java语言为Stri ...