使用HttpHandler为图片添加水印
需求:
1、为所有的大图添加水印
2、不要直接在图片上生成水印,要保持图片的原汁原味
3、要求可配置,配置的选项包括是否启用水印,水印图片可以更换,水印的位置可以更换
解决方案:
在我们的图片管理系统中,用户上传的图片都通过一个二级域名进行管理,如 images.photocms.com
所以就只需在这个应用中,拦截所有的图片请求交由asp.net处理,在asp.net程序中处理原图和水印图片,
将结果输出给用户即可。
具体步骤如下:
1、配置IIS,将jpg后缀名的请求用aspnet_isapi.dll来接收处理。
2、配置Web.config ,添加.jpg处理程序对应的具体asp.net类
<add verb="*" path="*.jpg" type="PhotoCms.Common.WaterMark,PhotoCms.Common" />
具体技术实现:
其中具体的 HttpHandler 程序
public class WaterMark : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
HttpResponse Response = context.Response;
HttpRequest Request = context.Request;
Response.ContentType = "image/jpeg";
string filePath = Request.FilePath;
string physicalPath = context.Server.MapPath(filePath);
if (!File.Exists(physicalPath))
return;
string waterImagePath = context.Server.MapPath("/watermark.png");
IList<string> ruleList=new List<string>();
string isOpen=string.Empty;
int padding = 10;
watermarkConfig objWaterConfig = watermarkConfig.GetInstance();
if (objWaterConfig != null)
{
isOpen=objWaterConfig.isOpen;
waterImagePath = context.Server.MapPath(objWaterConfig.filePath);
ruleList = objWaterConfig.rules;
padding = objWaterConfig.padding;
}
bool doWaterMark=false;
foreach(string _rule in ruleList)
{
if(filePath.Contains(_rule))
{
doWaterMark=true;
continue;
}
}
if(isOpen.Equals("1") && doWaterMark)
{
physicalPath = context.Server.MapPath(filePath);
ImageHelper obj = new ImageHelper(physicalPath);
obj.InsertImage(waterImagePath, Common.WathermarkPosition.BottomRight,padding);
obj.GetImage().Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
obj.Dispose();
}
else
{
physicalPath = context.Server.MapPath(filePath);
byte[] buffer = new Byte[10000];
int length;
long dataToRead;
System.IO.Stream iStream = null;
iStream = new System.IO.FileStream(physicalPath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
dataToRead = iStream.Length;
Response.Buffer = false;
while (dataToRead > 0)
{
if (Response.IsClientConnected)
{
length = iStream.Read(buffer, 0, 10000);
Response.OutputStream.Write(buffer, 0, length);
Response.Flush();
buffer = new Byte[10000];
dataToRead = dataToRead - length;
}
else
{
dataToRead = -1;
}
}
iStream.Close();
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
public class watermarkConfig
{
public string isOpen = string.Empty;
public string filePath = string.Empty;
public int padding = 0;
public IList<string> rules=new List<string>();
private static watermarkConfig instance;
private watermarkConfig()
{
loadConfigFile();
}
public static watermarkConfig GetInstance()
{
if (instance == null)
{
instance = new watermarkConfig();
}
return instance;
}
private void loadConfigFile()
{
string configFile = HttpContext.Current.Request.ApplicationPath + "/config/photo/photo.config";
XmlDocument xml = new XmlDocument();
xml.Load(HttpContext.Current.Server.MapPath(configFile));
XmlNode waterroot = xml.SelectSingleNode("picture/watermark");
this.isOpen = waterroot.Attributes["isOpen"].Value;
this.filePath = waterroot.Attributes["filePath"].Value;
this.padding = Convert.ToInt32(waterroot.Attributes["padding"].Value);
foreach(XmlNode rule in waterroot.ChildNodes)
{
if (rule.NodeType != XmlNodeType.Comment)
{
if (rule.Name.ToLower().Equals("rule"))
{
rules.Add(rule.Attributes["urlfrom"].Value);
}
}
}
}
}
public void ProcessRequest(HttpContext context)
{
HttpResponse Response = context.Response;
HttpRequest Request = context.Request;
Response.ContentType = "image/jpeg";
string filePath = Request.FilePath;
string physicalPath = context.Server.MapPath(filePath);
if (!File.Exists(physicalPath))
return;
string waterImagePath = context.Server.MapPath("/watermark.png");
IList<string> ruleList=new List<string>();
string isOpen=string.Empty;
int padding = 10;
watermarkConfig objWaterConfig = watermarkConfig.GetInstance();
if (objWaterConfig != null)
{
isOpen=objWaterConfig.isOpen;
waterImagePath = context.Server.MapPath(objWaterConfig.filePath);
ruleList = objWaterConfig.rules;
padding = objWaterConfig.padding;
}
bool doWaterMark=false;
foreach(string _rule in ruleList)
{
if(filePath.Contains(_rule))
{
doWaterMark=true;
continue;
}
}
if(isOpen.Equals("1") && doWaterMark)
{
physicalPath = context.Server.MapPath(filePath);
ImageHelper obj = new ImageHelper(physicalPath);
obj.InsertImage(waterImagePath, Common.WathermarkPosition.BottomRight,padding);
obj.GetImage().Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
obj.Dispose();
}
else
{
physicalPath = context.Server.MapPath(filePath);
byte[] buffer = new Byte[10000];
int length;
long dataToRead;
System.IO.Stream iStream = null;
iStream = new System.IO.FileStream(physicalPath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
dataToRead = iStream.Length;
Response.Buffer = false;
while (dataToRead > 0)
{
if (Response.IsClientConnected)
{
length = iStream.Read(buffer, 0, 10000);
Response.OutputStream.Write(buffer, 0, length);
Response.Flush();
buffer = new Byte[10000];
dataToRead = dataToRead - length;
}
else
{
dataToRead = -1;
}
}
iStream.Close();
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
public class watermarkConfig
{
public string isOpen = string.Empty;
public string filePath = string.Empty;
public int padding = 0;
public IList<string> rules=new List<string>();
private static watermarkConfig instance;
private watermarkConfig()
{
loadConfigFile();
}
public static watermarkConfig GetInstance()
{
if (instance == null)
{
instance = new watermarkConfig();
}
return instance;
}
private void loadConfigFile()
{
string configFile = HttpContext.Current.Request.ApplicationPath + "/config/photo/photo.config";
XmlDocument xml = new XmlDocument();
xml.Load(HttpContext.Current.Server.MapPath(configFile));
XmlNode waterroot = xml.SelectSingleNode("picture/watermark");
this.isOpen = waterroot.Attributes["isOpen"].Value;
this.filePath = waterroot.Attributes["filePath"].Value;
this.padding = Convert.ToInt32(waterroot.Attributes["padding"].Value);
foreach(XmlNode rule in waterroot.ChildNodes)
{
if (rule.NodeType != XmlNodeType.Comment)
{
if (rule.Name.ToLower().Equals("rule"))
{
rules.Add(rule.Attributes["urlfrom"].Value);
}
}
}
}
}
/config/photo/photo.config 的内容
<!--水印设置,isOpen 1开启水印 其他值关闭,filePath 水印图片的物理路径, rule 包含哪些字符串的图片需要加水印-->
<watermark isOpen="1" filePath="~/watermark.png" padding="100">
<rule urlfrom="/photo/e0"></rule>
<rule urlfrom="/photo/f0"></rule>
<rule urlfrom="/photo/a0"></rule>
</watermark>