給圖片添加水印,一般的做法是在上傳圖片時直接給圖片添加上水印,由於我在項目中使用了FCKeditor,在上傳時不易控制,同時對方還要求他們自己用時不能有水印,於是我就使用了在圖片顯示時動態添加水印的辦法,另外,爲了提高效率,還使用了緩存技術,這樣不必每次都添加水印,節省時間和提高性能。
本文中使用到的類是IHttpHandler(準確地說是一個接口),msdn對它的定義是:“定義 ASP.NET 爲使用自定義 HTTP 處理程序同步處理 HTTP Web 請求而實現的協定。”HTTP處理程序是實現了System.Web.IHttpHandler接口的.NET組件,任何實現了IHttpHandler接口的類都可以用於處理輸入的HTTP請求。也就是每次我們請求asp.net網站上的資源,都會由這個請求處理,這樣就好控制了。
我的做法是,實現IHttpHandler接口,由實現這個接口的ImageHandler類專門處理對圖片資源的請求,第一次請求某個圖片時,由於緩存中沒有,就讀取這個圖片,添加上我們指定的水印(由web.config設置指定),然後把輸出到客戶端,同時也把它緩存一定時間,在緩存期內就再次請求這個圖片就不用添加水印了,直接把緩存中的圖片輸出就行了。
首先我們要編寫自己的類ImageHandler實現IHttpHandler接口,代碼如下:
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Drawing;
using System.Drawing.Imaging;
/// <summary>
///ImageHandler 的摘要說明
/// </summary>
public class ImageHandler:IHttpHandler
{
public ImageHandler()
{
//
//TODO: 在此處添加構造函數邏輯
//
}
#region IHttpHandler 成員
public bool IsReusable
{
get { return true ; }
}
public void Proce***equest(HttpContext context)
{
string imagepath = context.Request.PhysicalPath;
Bitmap image = null;
if (context.Cache[imagepath] == null)
{
image = new Bitmap(imagepath);
image = AddWaterMark(image);
context.Cache[imagepath] = image;
}
else
{
image = context.Cache[imagepath] as Bitmap;
}
image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
}
//給圖片添加水印
private Bitmap AddWaterMark(Bitmap image)
{
string text = System.Configuration.ConfigurationManager.AppSettings["WaterMark"].ToString();
int fontSize = int.Parse(System.Configuration.ConfigurationManager.AppSettings["Font-Size"].ToString());
Font font = new Font("宋體", fontSize);
//Brush brush = Brushes.DarkGray;
Brush brush = Brushes.Red;
Graphics g = Graphics.FromImage(image);
SizeF size = g.MeasureString(text, font);
g.DrawString(text, font, brush, image.Width - size.Width, image.Height - size.Height);
g.Dispose();
return image;
}
#endregion
}
可以把這個類編譯成一個單獨的dll文件,不過我現在是演示,直接放在了App_Code文件夾下了。
html頁面如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>無標題頁</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<img src="Images/1.jpg" /><br />
<img src="Images/2.jpg" /><br />
<img src="3.jpg" /><br />
</div>
</form>
</body>
</html>
最後我們還需要對web.config做一些配置,一是定義我們要添加的水印文字,二是定義文字大小,三是將我們自己的HttpHandler註冊到網站,我的web.config文件如下:
<!--
注意: 除了手動編輯此文件以外,您還可以使用
Web 管理工具來配置應用程序的設置。可以使用 Visual Studio 中的
“網站”->“Asp.Net 配置”選項。
設置和註釋的完整列表在
machine.config.comments 中,該文件通常位於
WindowsMicrosoft.NetFrameworkv2.xConfig 中
-->
<configuration>
<appSettings>
<!--添加到圖片上的水印文字-->
<add key="WaterMark" value="公司網址"/>
<!--水印文字的字體大小-->
<add key="Font-Size" value="14"/>
</appSettings>
<connectionStrings/>
<system.web>
<compilation debug="true"/>
<!--
通過 <authentication> 節可以配置 ASP.NET 使用的
安全身份驗證模式,
以標識傳入的用戶。
-->
<authentication mode="Windows"/>
<httpHandlers>
<!--只處理UploadImages目錄下的jpg文件,別的目錄下的圖片不處理-->
<add path="Images/*.jpg" verb="*" type="ImageHandler"/>
</httpHandlers>
</system.web>
</configuration>
它表明只處理網站根目錄下的Images文件夾中的圖片,在本實例中Upload文件夾也有圖片,可是這個文件夾下的圖片是網站logo等常規圖片,不需要處理,所以這個元素的path屬性值是:path="Images/*.jpg",如果你想給所有jpg圖片添加水印,可以寫成path="*.jpg",在接下來的頁面中我們就會看到結果如我們所願,在Upload目錄下的圖片真的沒有添加水印,而在Images確實添加了水印!
最後說明:(一)在這兒我將水印文字字體設置爲14,同時還是用了醒目的紅色,在實際項目中需要根據圖片大小計算文字大小,文字顏色不宜過於鮮明;(二)爲了演示,緩存使用過於簡單,還可以進行一些更負責的設置,更大程度節省內存。(三)添加水印圖片原理也很簡單,使用GDI+將水印圖片畫在要添加水印的圖片上即可;(四)即使單獨在地址欄輸入圖片的url地址,看到的圖片也一樣會有水印。