我(wo)心中的核心組件~HttpHandler和HttpModule實現(xian)圖像的縮放與Url的重寫
說在前
對于資源列表頁來說,我們經常會把圖像做成N多種,大圖,小圖,中圖等等,很是麻煩,在數據遷移時,更是一種痛快,而如果你把圖像資源部署到nginx上,那么這種圖像縮放就變得很容易了,因為它有自己的過濾器來實現這個功能,只要程序員簡單的配置即可(GraphicsMagick),其實在nginx上實現縮略圖的方式有很多,而對于IIS服務來說,實現這種縮略圖就沒有直接的方法了,必須開發人員自己寫代碼來實現,下面解釋兩個比較早的技術(被執行的期間比較早,在頁面渲染之前)HttpModule和httpHandler,這兩個東西我在之前的文章中也已經講過,細節不再重復。[HttpModule幾大事件,HttpHandler實現圖像防盜鏈]
做在后
一(yi) HttpModule對(dui)URL地(di)(di)址進行(xing)重寫(xie),將(jiang)擴(kuo)展(zhan)名(ming)為jpg,jpeg,png,gif結尾(wei)的URL地(di)(di)址進行(xing)復寫(xie),讓它支持漂(piao)(piao)亮(liang)的縮(suo)(suo)略圖參數(shu),如(ru)原(yuan)地(di)(di)址為:new1.jpg,實現縮(suo)(suo)略圖原(yuan)地(di)(di)址為:new1.jpg?w=100&h=100,進行(xing)Url重寫(xie)后的漂(piao)(piao)亮(liang)地(di)(di)址為:new1_100x100.jpg,怎么樣,是否是很(hen)漂(piao)(piao)亮(liang),有點像(xiang)MVC 的router吧,呵呵
/// <summary> /// 實現URL的(de)重寫(xie) /// </summary> public class UrlRewriteModule : IHttpModule { #region IHttpModule 成員 public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(Application_BeginRequest); } /// <summary> /// url重寫 /// .png?w=100&h=100 /// _100x100.png /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Application_BeginRequest(Object sender, EventArgs e) { string oldUrl = HttpContext.Current.Request.RawUrl; if (oldUrl.LastIndexOf(".") > -1) { string ext = oldUrl.Substring(oldUrl.LastIndexOf(".")).ToLower(); //是圖像文件 if (ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == "gif") { var param = oldUrl.Substring(oldUrl.LastIndexOf("_") + 1, (oldUrl.IndexOf(".") - oldUrl.LastIndexOf("_") - 1)).Split(new char[] { 'x' }, StringSplitOptions.RemoveEmptyEntries); //有圖像縮放(fang)請(qing)求 if (oldUrl.LastIndexOf("_") > -1) { string newUrl = oldUrl.Substring(0, oldUrl.LastIndexOf("_")); newUrl = string.Format(newUrl + ext + "?w={0}&h={1}", param[0], param[1]); //將請(qing)求(qiu)中的(de)URL進行重寫 HttpContext.Current.RewritePath(newUrl); } } } } #endregion #region IHttpModule 成員 public void Dispose() { } #endregion }
二(er) 使用HttpHandler進行對圖(tu)像的(de)(de)縮放,你的(de)(de)服務器是指與圖(tu)像資(zi)源(yuan)在(zai)一起(qi)的(de)(de)那臺電腦
/// <summary> /// 圖片(pian)動態縮放處理程序 /// </summary> public class ImageScalingHandler : IHttpHandler { /// <summary> /// 圖像等比例縮放,圖像默認(ren)為白色 /// </summary> /// <param name="image"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> private Bitmap CreateThumbnail(Image image, int width, int height) { Point point = new Point(0, 0); //圖像(xiang)從那(nei)個坐標(biao)點進行截(jie)取 double wRate = 1, hRate = 1, setRate = 1; int newWidth = 0, newHeight = 0; try { if (width == 0) width = image.Width; if (height == 0) height = image.Height; if (image.Height > height) { hRate = (double)height / image.Height; } if (image.Width > width) { wRate = (double)width / image.Width; } if (wRate != 1 || hRate != 1) { if (wRate > hRate) { setRate = hRate; } else { setRate = wRate; } } newWidth = (int)(image.Width * setRate); newHeight = (int)(image.Height * setRate); if (height > newHeight) { point.Y = Convert.ToInt32(height / 2 - newHeight / 2); } if (width > newWidth) { point.X = Convert.ToInt32(width / 2 - newWidth / 2); } Bitmap bit = new Bitmap(width, height); Rectangle r = new Rectangle(point.X, point.Y, (int)(image.Width * setRate), (int)(image.Height * setRate)); Graphics g = Graphics.FromImage(bit); g.Clear(Color.White); g.DrawImage(image, r); g.Dispose(); return bit; } catch (Exception) { throw; } } /// <summary> /// 處(chu)理請求(qiu) /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) { int w = 0, h = 0; int.TryParse(context.Request.QueryString["w"], out w); int.TryParse(context.Request.QueryString["h"], out h); Image image = Image.FromFile(context.Request.PhysicalPath); context.Response.ContentType = "image/jpeg"; Bitmap bitMap = CreateThumbnail(image, w, h); bitMap.Save(context.Response.OutputStream, ImageFormat.Jpeg); image.Dispose(); bitMap.Dispose(); context.Response.End(); } public bool IsReusable { get { return false; } } }
三 最后就是在Module和Handler的入口配置(zhi)的,即(ji)如何將(jiang)它們加(jia)入到(dao)當然網站中(zhong),我們采用(yong)web.config配置(zhi)的方(fang)法
<system.web>
<httpModules>
<!-- this is for Classic mode and Cassini -->
<add name="UrlRewriteModule" type="EntityFrameworks.Web.Core.HttpModules.UrlRewriteModule,EntityFrameworks.Web.Core" />
</httpModules>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" >
<!--This is for Integrated mode-->
<add name="UrlRewriteModule" type="EntityFrameworks.Web.Core.HttpModules.UrlRewriteModule,EntityFrameworks.Web.Core" />
</modules>
<handlers>
<add name="ImageFunction1" path="*.jpg" verb="GET" type="EntityFrameworks.Web.Core.HttpHandlers.ImageScalingHandler,EntityFrameworks.Web.Core" />
<add name="ImageFunction2" path="*.png" verb="GET" type="EntityFrameworks.Web.Core.HttpHandlers.ImageScalingHandler,EntityFrameworks.Web.Core" />
<add name="ImageFunction3" path="*.gif" verb="GET" type="EntityFrameworks.Web.Core.HttpHandlers.ImageScalingHandler,EntityFrameworks.Web.Core" />
<add name="ImageFunction4" path="*.jpeg" verb="GET" type="EntityFrameworks.Web.Core.HttpHandlers.ImageScalingHandler,EntityFrameworks.Web.Core" />
</handlers>
從(cong)上面的代碼(ma)中,我(wo)們可以看到(dao),對于modules來說,那有(you)兩(liang)種方式注(zhu)入,一為IIS經典模(mo)式下的,另一種是(shi)IIS集成模(mo)式下的,我(wo)們需(xu)要分別(bie)進行配置(zhi)。
可以看一下效果,成功(gong)的(de)喜悅!
大叔框架(jia)集(ji)又一成功組(zu)件...