IHttphandler原理已经在“IHttphandler之Url重写”一文中讲述,有不理解的同学可以参看该文章。
本文是对网站的图片进行水印处理。原理相同,关键在web.config的配置,以及GDI+操作。
首先对web.config配置如下:
<httpHandlers>
<add verb="*" path="*.jpg" type="MyHttpHandler.WaterMarkHandler,MyHttpHandler"/> </httpHandlers>
为什么要这么配置同样参见“IHttphandler之Url重写”一文,path为“*.jpg”,例如“logo.gif”的时候,由MyHttpHandler.WaterMarkHandler处理后返回客户端。
让我们来看下WaterMarkHandler的实现吧:
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Web;
using
System.Drawing;
using
System.Drawing.Imaging;
using
System.IO;
namespace
MyHttpHandler
{
class
WaterMarkHandler : IHttpHandler
{
#region
IHttpHandler 成员
public
bool
IsReusable
{
get
{
return
true
; }
}
public
void
ProcessRequest(HttpContext context)
{
CommonDeal.DealImageRequest(context);
}
#endregion
}
}
CommonDeal实现如下:
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Web;
using
System.Web.UI;
using
System.IO;
using
System.Drawing;
using
System.Drawing.Imaging;
namespace
MyHttpHandler
{
internal
class
CommonDeal
{
public
static
void
DealImageRequest(HttpContext context)
{
Font enFont
=
new
Font(
"
Times New Roman
"
,
12
);
MemoryStream ms
=
new
MemoryStream();
string
filePath
=
context.Server.MapPath(
"
Image
"
+
context.Request.Path);
try
{
Image image
=
Image.FromFile(filePath);
if
(IsPixelFormatIndexed(image.PixelFormat))
{
Bitmap bmp
=
new
Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb);
using
(Graphics graphic
=
Graphics.FromImage(bmp))
{
graphic.InterpolationMode
=
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode
=
System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphic.CompositingQuality
=
System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphic.DrawImage(image,
0
,
0
);
graphic.DrawString(
"
pangxiaoliang
"
, enFont,
new
SolidBrush(Color.LightGray),
2
,
2
);
graphic.DrawString(
"
pangxiaoliang
"
, enFont,
new
SolidBrush(Color.Black),
0
,
0
);
}
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
bmp.Dispose();
}
else
{
using
(Graphics graphic
=
Graphics.FromImage(image))
{
graphic.DrawString(
"
pangxiaoliang
"
, enFont,
new
SolidBrush(Color.LightGray),
2
,
2
);
graphic.DrawString(
"
pangxiaoliang
"
, enFont,
new
SolidBrush(Color.Black),
0
,
0
);
}
Bitmap theBitmap
=
new
Bitmap(image);
theBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
theBitmap.Dispose();
}
context.Response.ClearContent();
context.Response.ContentType
=
"
image/jpg
"
;
context.Response.BinaryWrite(ms.ToArray());
}
catch
{
Bitmap error
=
new
Bitmap(context.Server.MapPath(
"
Image/error.bmp
"
));
error.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
error.Dispose();
context.Response.ClearContent();
context.Response.ContentType
=
"
image/jpg
"
;
context.Response.BinaryWrite(ms.ToArray());
}
finally
{
ms.Close();
ms.Dispose();
context.Response.End();
}
}
public
static
void
ReturnErrorImage(HttpContext context)
{
MemoryStream ms
=
new
MemoryStream();
try
{
Bitmap error
=
new
Bitmap(context.Server.MapPath(
"
error.bmp
"
));
error.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
error.Dispose();
context.Response.ClearContent();
context.Response.ContentType
=
"
image/jpg
"
;
context.Response.BinaryWrite(ms.ToArray());
}
catch
{
}
finally
{
ms.Close();
ms.Dispose();
context.Response.End();
}
}
///
<summary>
///
会产生graphics异常的PixelFormat
///
</summary>
private
static
PixelFormat[] indexedPixelFormats
=
{ PixelFormat.Undefined, PixelFormat.DontCare,
PixelFormat.Format16bppArgb1555, PixelFormat.Format1bppIndexed, PixelFormat.Format4bppIndexed,
PixelFormat.Format8bppIndexed
};
///
<summary>
///
判断图片的PixelFormat 是否在 引发异常的 PixelFormat 之中
///
</summary>
///
<param name="imgPixelFormat">
原图片的PixelFormat
</param>
///
<returns></returns>
private
static
bool
IsPixelFormatIndexed(PixelFormat imgPixelFormat)
{
foreach
(PixelFormat pf
in
indexedPixelFormats)
{
if
(pf.Equals(imgPixelFormat))
return
true
;
}
return
false
;
}
}
}
1)string filePath = context.Server.MapPath("Image" + context.Request.Path);首先得到图像在服务器上的绝对路径,使得可以对图像进行处理。
2)MemoryStream ms = new MemoryStream();内存流用来响应客户端请求,把处理后的图像返回给客户端。
3)使用GDI+对在图像上写上名字后,以流的方式将新图片返回到客户端。