一.引言
目前的许多网站,为了保护着作权,通常需在图片上嵌入水印.嵌入水 印可以通过图像编辑软件(如PhotoShop)直接手工在原始图片上进行修改,但 这种方法费时又费力,几乎任何网站都不会采用此方法;或通过GUI+编写程序来 批量处理图片.但这这些方法都将破坏原始图片的完整性.本文介绍的方法,利 用了HttpHandler处理Http请求的机制,只将要呈现在Web页上的图片嵌入水印, 而不会对文件系统中的原始图片做任何修改,有效地保证了原始图片的完整性.
二.相关技术
1. ASP.NET中处理Http请求是基于管道模型,这条管道由多个HttpModule 和一个HttpHandler组成,ASP.NET把Http请求依次传递给管道中各个HttpModule, 最终被HttpHandler处理,处理完成后,再依次经过管道中的HttpModule, 把结果 返回给客户端(如图).
2. 当Http请求到达HttpModule的时候,系统并没有对这个请求真正处理,但是 可以在这个请求传递到HttpHandler之前附加一些其它功能,比如访问Session.
在HttpHandler处理完请求之后,还可以再在相应的HttpModule中把请求处理的 结果再次进行加工后返回客户端.
3. HttpHandler才是Http请求的处理中心,真正地对客户端请求的服务器页面做 出编译和执行,并将处理过后的信息附加在Http请求信息流中再次返回到HttpModule 中,HttpHandler功能的通过必须实现IHttpHandler接口.
4. IHttpHandler接口定义如下:
public interface IHttpHandler { //处理请求 public void ProcessRequest(HttpContext context); //其他请求是否可以使用 IHttpHandler 实例 bool IsReusable { get; } }
5. ProcessRequest(HttpContext context)方法的参数context属HttpContext类型.
其中HttpContext.Request属HttpRequest类,使 ASP.NET 能够读取客户端在 Web 请求期间发送的 Http 值;HttpContext.Response属HttpResponse类,HttpResponse类 封装了来自 ASP.NET 操作的 Http 响应信息,可以利用它将处理后的结果输出到Web页面.
三.解决方案要点
1.在App_Code文件夹中创建实现IHttpHandler接口的类WaterMarkHandler;
2. 在WaterMarkHandler中实现ProcessRequest(HttpContext context)方法, 通过参数HttpContext.Request.PhysicalPath获取图片的物理路径,以此创建一个 Image实例;
3.使用Graphics把Image实例和水印图片叠加;
4.通过HttpContext.Response输出叠加后的图片;
5.配置Web.Config.
四.程序实现
1.在网站根文件夹下创建图片文件夹images,将若干需嵌入水印的图片和水印图片 watermark.jpg拷至其中;
2.在App_Code文件夹中创建类WaterMarkHandler.cs,代码如下:
using System; using System.Web; using System.Drawing; using System.Drawing.Imaging; using System.IO; //实现IHttpHandler public class WaterMarkHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { // Request的PhysicalPath获取与请求的URL相对应的物理文件路径 //Image myImage =Image.FromFile(context.Request.PhysicalPath); // MapPath方法将水印图片的虚拟路径映射到服务器上的物理路径 Image watermark = Image.FromFile(context.Request.MapPath(@"~/images/watermark.jpg")); //创建Graphics实例 Graphics myGraphcs = Graphics.FromImage(myImage); //将水印叠加到图片右下角,这里水印位置可根据需要自行设置 myGraphcs.DrawImage(watermark,myImage.Width-watermark.Width,myImage.Height-watermark.Height,watermark.Width,watermark.Height); myGraphcs.Dispose(); watermark.Dispose(); context.Response.ContentType = "image/jpeg"; //将叠加后的图片以指定的格式保存到Response的输出流中。 myImage.Save (context.Response.OutputStream,ImageFormat.Jpeg); myImage.Dispose(); context.Response.End(); } public bool IsReusable { get { return false;} } }
3.在Web.config的System.Web节中添加如下代码:
<HttpHandlers> <add verb="*" path="images/*.jpg" type=" WaterMarkHandler"/> </HttpHandlers>
其中:
(1)verb是逗号分隔的 Http 谓词列表(例如:"GET、PUT、POST"), 可以是开始脚本映射,比如星号"*"通配符,这里表示所有请求.
(2)path是访问路径,这里表示访问images文件夹中所有的.jpg文件.
(3)type指定逗号分隔的类/程序集组合.ASP.NET 首先在应用程序的专用 bin 目录中搜索程序集 DLL,然后在系统程序集缓存中搜索程序集 DLL,这里表示凡是访问images文件夹中的.jpg文件的请求都将执行 WaterMarkHandler中的代码.
五.结束语
以上方案利用HttpHandler处理Http请求的机制为图片动态地嵌入水印提供了一种切实可行的方法,可以看出此方法简单且易理解.本文只给出了HttpHandler的应用, 其实我们还可以通过HttpModule解决许多实际问题,如弹出广告、输出版权信息等等, 鉴于篇幅所限,这里就不再赘述.
本文转自:http://www.gzweix.com/article/sort0247/sort0379/sort0389/info-155816_2.html