ASP.NET 图片加水印防盗链实现代码
程序员文章站
2024-03-06 13:46:14
首先建一个类: 复制代码 代码如下: using system; using system.collections.generic; using system.linq;...
首先建一个类:
using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.drawing;
/// <summary>
///class1 的摘要说明
/// </summary>
public class class1:ihttphandler //调用接口
{
public class1()
{
//
//todo: 在此处添加构造函数逻辑
//
}
public bool isreusable
{
get { return true; }
}
public void processrequest(httpcontext context)
{
httprequest req = context.request;
if (req.urlreferrer != null && req.urlreferrer.host.length > 0) //反盗链代码判断
{
system.drawing.image img = system.drawing.image.fromfile(context.request.physicalpath);
system.drawing.graphics g = graphics.fromimage(img);
g.drawstring("三国演义", new font("宋体", 20, fontstyle.bold), brushes.white, 10, 10);
img.save(context.response.outputstream, system.drawing.imaging.imageformat.jpeg);
context.response.flush();
context.response.end();
}
else
{
context.response.write("您不能盗链本站图片");
}
}
}
在web.config中注册接口:
<httphandlers>
<add verb="*" path="images/*.jpg" type="class1,app_code"/>
</httphandlers>
url:http://greatverve.cnblogs.com/archive/2011/12/20/asp-net-hotlinking.html
参考:
1.修改web.config
<system.web>
<httphandlers>
<remove verb="*" path="*.asmx"/>
<!--解决图片防盗链问题-->
<add verb="*" path="*.jpg" type="myhttphandler.watermark"/>
<add verb="*" path="*.gif" type="myhttphandler.watermark"/>
<add verb="*" path="*.png" type="myhttphandler.watermark"/>
</httphandlers>
</system.web>
2.添加一个一般执行文件watermark.ashx,代码如下:
using system;
using system.data;
using system.web;
using system.collections;
using system.web.services;
using system.web.services.protocols;
using system.drawing.imaging;
using system.drawing;
using system.io;
namespace myhttphandler
{
/// <summary>
/// summary description for $codebehindclassname$
/// </summary>
[webservice(namespace = "http://tempuri.org/")]
[webservicebinding(conformsto = wsiprofiles.basicprofile1_1)]
public class watermark : ihttphandler
{
public bool isreusable
{
get
{
return false;
}
}
public void processrequest(httpcontext context)
{
//设置客户端缓冲时间过期时间为0,即立即过期
//context.response.expires = 0;
//清空服务器端为此会话开启的输出缓存
//context.response.clear();
//设置输出文件类型
context.response.contenttype = "image/jpg";
//将请求文件写入到输出缓存中
#region 获取xml配置信息
dataset dsconfing = new dataset();
string watermarkconfigpath = context.server.mappath("~/config/watermarkconfig.xml");
if (system.io.file.exists(watermarkconfigpath))
dsconfing.readxml(watermarkconfigpath);
else
{
//添加默认的水印配置
}
datarow drconfing = dsconfing.tables[0].rows[0];
#endregion
string currenthost = drconfing["allowhost"].tostring();
//判断是否是本地网站引用图片,如果是则返回正确的图片
if (context.request.url.authority.equals(currenthost, stringcomparison.invariantcultureignorecase))
{
string localpath = context.request.url.localpath;
localpath = localpath.remove(localpath.lastindexof('/')).tolower();// "/images/userphoto"
if (drconfing["isflag"].equals("true") && drconfing["files"].tostring().tolower().indexof(localpath) > 0)
{
#region 水印代码
string simgstartphysicalpath = context.request.physicalpath;
system.drawing.image imgstart = system.drawing.image.fromfile(simgstartphysicalpath);
//备份原图片
//int indexof = simgstartphysicalpath.lastindexof(".");
//string bakpath = simgstartphysicalpath.remove(indexof) + "_bak" + simgstartphysicalpath.substring(indexof);
//imgstart.save(bakpath);
graphics gh = system.drawing.graphics.fromimage(imgstart);
if (drconfing["type"].equals("img"))
{
system.drawing.image imgwatermark = system.drawing.image.fromfile(context.server.mappath(drconfing["img-path"].tostring()));
rectangle rg = setimgposition(drconfing["position"].tostring(), imgstart.width, imgstart.height, imgwatermark.width, imgwatermark.height);
gh.drawimage(imgwatermark, rg, 0, 0, imgwatermark.width, imgwatermark.height, graphicsunit.pixel);
gh.save();
gh.dispose();
imgwatermark.dispose();
}
else if (drconfing["type"].equals("font"))
{
//文字水印
string content = drconfing["font-content"].tostring();
float size = (float)convert.todouble(drconfing["font-size"].tostring());
fontstyle fontstyle = (fontstyle)int.parse(drconfing["font-style"].tostring());
system.drawing.font f = new system.drawing.font("arial", size, fontstyle);
color g_color = color.fromname(drconfing["font-color"].tostring());
system.drawing.brush b = new system.drawing.solidbrush(g_color);
sizef sizef = gh.measurestring(content, f);
gh.drawstring(content, f, b, setfontposition(drconfing["position"].tostring(), imgstart.width, imgstart.height, (int)sizef.width, (int)sizef.height));
gh.save();
gh.dispose();
}
//将请求文件写入到输出缓存中
imgstart.save(context.response.outputstream, imageformat.jpeg);
imgstart.dispose();
#endregion
}
else
{
#region 输出原图
//将请求文件写入到输出缓存中
context.response.writefile(context.request.url.absolutepath);
#endregion
}
}
//如果不是本地引用,则是盗链本站图片
else
{
//将请求文件写入到输出缓存中
context.response.writefile(context.request.physicalapplicationpath + drconfing["errimgpath"].tostring());
}
//将输出缓存中的信息传送到客户端
context.response.end();
}
/// <summary>
/// 图片绘画水印的位置
/// </summary>
/// <param name="positionconfig">位置类型</param>
/// <param name="width">原图片宽</param>
/// <param name="height"></param>
/// <param name="watermarkwidth">水印图宽</param>
/// <param name="watermarkheight"></param>
/// <returns></returns>
private rectangle setimgposition(string positionconfig,int width,int height,int watermarkwidth,int watermarkheight)
{
int xpos = 0;
int ypos = 0;
int margin = 10;
int width_margin = width - margin;
int height_margin = height - margin;
double proportion = 1d;//水印图片缩放比例
//int
if ((width_margin > watermarkwidth * proportion) && (height_margin > watermarkheight * proportion))
{
}
else if ((width_margin > watermarkwidth * proportion) && (height_margin < watermarkheight * proportion))
{
proportion = convert.todouble( height_margin) / convert.todouble( watermarkheight);
}
else if ((width_margin < watermarkwidth * proportion) && (height_margin > watermarkheight * proportion))
{
proportion = convert.todouble(width_margin) / convert.todouble(watermarkwidth);
}
else
{
double proportionw = convert.todouble(width_margin) / convert.todouble(watermarkwidth);
double proportionh = convert.todouble(height_margin) / convert.todouble(watermarkheight);
proportion = proportionw >= proportionh ? proportionh : proportionw;
}
watermarkwidth = convert.toint32(watermarkwidth * proportion);
watermarkheight = convert.toint32(watermarkheight * proportion);
switch (positionconfig)
{
case "top-left":
xpos = margin;
ypos = margin;
break;
case "top-right":
xpos = width_margin - watermarkwidth;
ypos = margin;
break;
case "bottom-left":
xpos = margin;
ypos = height_margin - watermarkheight;
break;
case "bottom-right":
xpos = width_margin - watermarkwidth ;
ypos = height_margin - watermarkheight ;
break;
default:
xpos = width_margin - watermarkwidth ;
ypos = height_margin - watermarkheight;
break;
}
return new rectangle(xpos,ypos,watermarkwidth,watermarkheight);
}
/// <summary>
/// 图片绘画文字位置
/// </summary>
/// <param name="positionconfig">位置类型</param>
/// <param name="width">原图片宽</param>
/// <param name="height"></param>
/// <param name="fontwidth">文字长度</param>
/// <param name="fontheight"></param>
/// <returns></returns>
private point setfontposition(string positionconfig, int width, int height, int fontwidth, int fontheight)
{
int xpos = 0;
int ypos = 0;
int margin = 10;
int width_margin = width - margin;
int height_margin = height - margin;
double proportion = 1d;//水印图片缩放比例
//int
if ((width_margin > fontwidth * proportion) && (height_margin > fontheight * proportion))
{
}
else if ((width_margin > fontwidth * proportion) && (height_margin < fontheight * proportion))
{
proportion = convert.todouble(height_margin) / convert.todouble(fontheight);
}
else if ((width_margin < fontwidth * proportion) && (height_margin > fontheight * proportion))
{
proportion = convert.todouble(width_margin) / convert.todouble(fontwidth);
}
else
{
double proportionh = convert.todouble(height_margin) / convert.todouble(fontheight);
double proportionw = convert.todouble(width_margin) / convert.todouble(fontwidth);
proportion = proportionw >= proportionh ? proportionh : proportionw;
}
fontwidth = convert.toint32(fontwidth * proportion);
fontheight = convert.toint32(fontheight * proportion);
switch (positionconfig)
{
case "top-left":
xpos = margin;
ypos = margin;
break;
case "top-right":
xpos = width_margin - fontwidth;
ypos = margin;
break;
case "bottom-left":
xpos = margin;
ypos = height_margin - fontheight;
break;
case "bottom-right":
xpos = width_margin - fontwidth;
ypos = height_margin - fontheight;
break;
default:
xpos = width_margin - fontwidth;
ypos = height_margin - fontheight;
break;
}
return new point(xpos, ypos);
}
}
}
3.配置文件的watermarkconfig.xml,内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<watermark>
<allowhost>localhost:6219</allowhost><!--允许访问的域名-->
<isflag>true</isflag><!-- true、false-->
<type>font</type><!-- img、font-->
<files>/config|/upfiles/ab</files><!--需要加水印的文件夹-->
<position>bottom-right</position><!-- top-left、top-right、bottom-left、bottom-right-->
<img-path>~/upfiles/watermark.png</img-path><!-- 水印位置 -->
<font-style>1</font-style><!--普通文本 0, 加粗文本 1, 倾斜文本 2, 带下划线的文本 4, 中间有直线通过的文本 8-->
<font-size>60</font-size>
<font-color>red</font-color>
<font-content>¥:8000元</font-content>
<errimgpath>images/error.jpg</errimgpath><!-- 盗图片的请求返回的跟目录下的某图片 -->
</watermark>
复制代码 代码如下:
using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.drawing;
/// <summary>
///class1 的摘要说明
/// </summary>
public class class1:ihttphandler //调用接口
{
public class1()
{
//
//todo: 在此处添加构造函数逻辑
//
}
public bool isreusable
{
get { return true; }
}
public void processrequest(httpcontext context)
{
httprequest req = context.request;
if (req.urlreferrer != null && req.urlreferrer.host.length > 0) //反盗链代码判断
{
system.drawing.image img = system.drawing.image.fromfile(context.request.physicalpath);
system.drawing.graphics g = graphics.fromimage(img);
g.drawstring("三国演义", new font("宋体", 20, fontstyle.bold), brushes.white, 10, 10);
img.save(context.response.outputstream, system.drawing.imaging.imageformat.jpeg);
context.response.flush();
context.response.end();
}
else
{
context.response.write("您不能盗链本站图片");
}
}
}
在web.config中注册接口:
复制代码 代码如下:
<httphandlers>
<add verb="*" path="images/*.jpg" type="class1,app_code"/>
</httphandlers>
url:http://greatverve.cnblogs.com/archive/2011/12/20/asp-net-hotlinking.html
参考:
1.修改web.config
复制代码 代码如下:
<system.web>
<httphandlers>
<remove verb="*" path="*.asmx"/>
<!--解决图片防盗链问题-->
<add verb="*" path="*.jpg" type="myhttphandler.watermark"/>
<add verb="*" path="*.gif" type="myhttphandler.watermark"/>
<add verb="*" path="*.png" type="myhttphandler.watermark"/>
</httphandlers>
</system.web>
2.添加一个一般执行文件watermark.ashx,代码如下:
复制代码 代码如下:
using system;
using system.data;
using system.web;
using system.collections;
using system.web.services;
using system.web.services.protocols;
using system.drawing.imaging;
using system.drawing;
using system.io;
namespace myhttphandler
{
/// <summary>
/// summary description for $codebehindclassname$
/// </summary>
[webservice(namespace = "http://tempuri.org/")]
[webservicebinding(conformsto = wsiprofiles.basicprofile1_1)]
public class watermark : ihttphandler
{
public bool isreusable
{
get
{
return false;
}
}
public void processrequest(httpcontext context)
{
//设置客户端缓冲时间过期时间为0,即立即过期
//context.response.expires = 0;
//清空服务器端为此会话开启的输出缓存
//context.response.clear();
//设置输出文件类型
context.response.contenttype = "image/jpg";
//将请求文件写入到输出缓存中
#region 获取xml配置信息
dataset dsconfing = new dataset();
string watermarkconfigpath = context.server.mappath("~/config/watermarkconfig.xml");
if (system.io.file.exists(watermarkconfigpath))
dsconfing.readxml(watermarkconfigpath);
else
{
//添加默认的水印配置
}
datarow drconfing = dsconfing.tables[0].rows[0];
#endregion
string currenthost = drconfing["allowhost"].tostring();
//判断是否是本地网站引用图片,如果是则返回正确的图片
if (context.request.url.authority.equals(currenthost, stringcomparison.invariantcultureignorecase))
{
string localpath = context.request.url.localpath;
localpath = localpath.remove(localpath.lastindexof('/')).tolower();// "/images/userphoto"
if (drconfing["isflag"].equals("true") && drconfing["files"].tostring().tolower().indexof(localpath) > 0)
{
#region 水印代码
string simgstartphysicalpath = context.request.physicalpath;
system.drawing.image imgstart = system.drawing.image.fromfile(simgstartphysicalpath);
//备份原图片
//int indexof = simgstartphysicalpath.lastindexof(".");
//string bakpath = simgstartphysicalpath.remove(indexof) + "_bak" + simgstartphysicalpath.substring(indexof);
//imgstart.save(bakpath);
graphics gh = system.drawing.graphics.fromimage(imgstart);
if (drconfing["type"].equals("img"))
{
system.drawing.image imgwatermark = system.drawing.image.fromfile(context.server.mappath(drconfing["img-path"].tostring()));
rectangle rg = setimgposition(drconfing["position"].tostring(), imgstart.width, imgstart.height, imgwatermark.width, imgwatermark.height);
gh.drawimage(imgwatermark, rg, 0, 0, imgwatermark.width, imgwatermark.height, graphicsunit.pixel);
gh.save();
gh.dispose();
imgwatermark.dispose();
}
else if (drconfing["type"].equals("font"))
{
//文字水印
string content = drconfing["font-content"].tostring();
float size = (float)convert.todouble(drconfing["font-size"].tostring());
fontstyle fontstyle = (fontstyle)int.parse(drconfing["font-style"].tostring());
system.drawing.font f = new system.drawing.font("arial", size, fontstyle);
color g_color = color.fromname(drconfing["font-color"].tostring());
system.drawing.brush b = new system.drawing.solidbrush(g_color);
sizef sizef = gh.measurestring(content, f);
gh.drawstring(content, f, b, setfontposition(drconfing["position"].tostring(), imgstart.width, imgstart.height, (int)sizef.width, (int)sizef.height));
gh.save();
gh.dispose();
}
//将请求文件写入到输出缓存中
imgstart.save(context.response.outputstream, imageformat.jpeg);
imgstart.dispose();
#endregion
}
else
{
#region 输出原图
//将请求文件写入到输出缓存中
context.response.writefile(context.request.url.absolutepath);
#endregion
}
}
//如果不是本地引用,则是盗链本站图片
else
{
//将请求文件写入到输出缓存中
context.response.writefile(context.request.physicalapplicationpath + drconfing["errimgpath"].tostring());
}
//将输出缓存中的信息传送到客户端
context.response.end();
}
/// <summary>
/// 图片绘画水印的位置
/// </summary>
/// <param name="positionconfig">位置类型</param>
/// <param name="width">原图片宽</param>
/// <param name="height"></param>
/// <param name="watermarkwidth">水印图宽</param>
/// <param name="watermarkheight"></param>
/// <returns></returns>
private rectangle setimgposition(string positionconfig,int width,int height,int watermarkwidth,int watermarkheight)
{
int xpos = 0;
int ypos = 0;
int margin = 10;
int width_margin = width - margin;
int height_margin = height - margin;
double proportion = 1d;//水印图片缩放比例
//int
if ((width_margin > watermarkwidth * proportion) && (height_margin > watermarkheight * proportion))
{
}
else if ((width_margin > watermarkwidth * proportion) && (height_margin < watermarkheight * proportion))
{
proportion = convert.todouble( height_margin) / convert.todouble( watermarkheight);
}
else if ((width_margin < watermarkwidth * proportion) && (height_margin > watermarkheight * proportion))
{
proportion = convert.todouble(width_margin) / convert.todouble(watermarkwidth);
}
else
{
double proportionw = convert.todouble(width_margin) / convert.todouble(watermarkwidth);
double proportionh = convert.todouble(height_margin) / convert.todouble(watermarkheight);
proportion = proportionw >= proportionh ? proportionh : proportionw;
}
watermarkwidth = convert.toint32(watermarkwidth * proportion);
watermarkheight = convert.toint32(watermarkheight * proportion);
switch (positionconfig)
{
case "top-left":
xpos = margin;
ypos = margin;
break;
case "top-right":
xpos = width_margin - watermarkwidth;
ypos = margin;
break;
case "bottom-left":
xpos = margin;
ypos = height_margin - watermarkheight;
break;
case "bottom-right":
xpos = width_margin - watermarkwidth ;
ypos = height_margin - watermarkheight ;
break;
default:
xpos = width_margin - watermarkwidth ;
ypos = height_margin - watermarkheight;
break;
}
return new rectangle(xpos,ypos,watermarkwidth,watermarkheight);
}
/// <summary>
/// 图片绘画文字位置
/// </summary>
/// <param name="positionconfig">位置类型</param>
/// <param name="width">原图片宽</param>
/// <param name="height"></param>
/// <param name="fontwidth">文字长度</param>
/// <param name="fontheight"></param>
/// <returns></returns>
private point setfontposition(string positionconfig, int width, int height, int fontwidth, int fontheight)
{
int xpos = 0;
int ypos = 0;
int margin = 10;
int width_margin = width - margin;
int height_margin = height - margin;
double proportion = 1d;//水印图片缩放比例
//int
if ((width_margin > fontwidth * proportion) && (height_margin > fontheight * proportion))
{
}
else if ((width_margin > fontwidth * proportion) && (height_margin < fontheight * proportion))
{
proportion = convert.todouble(height_margin) / convert.todouble(fontheight);
}
else if ((width_margin < fontwidth * proportion) && (height_margin > fontheight * proportion))
{
proportion = convert.todouble(width_margin) / convert.todouble(fontwidth);
}
else
{
double proportionh = convert.todouble(height_margin) / convert.todouble(fontheight);
double proportionw = convert.todouble(width_margin) / convert.todouble(fontwidth);
proportion = proportionw >= proportionh ? proportionh : proportionw;
}
fontwidth = convert.toint32(fontwidth * proportion);
fontheight = convert.toint32(fontheight * proportion);
switch (positionconfig)
{
case "top-left":
xpos = margin;
ypos = margin;
break;
case "top-right":
xpos = width_margin - fontwidth;
ypos = margin;
break;
case "bottom-left":
xpos = margin;
ypos = height_margin - fontheight;
break;
case "bottom-right":
xpos = width_margin - fontwidth;
ypos = height_margin - fontheight;
break;
default:
xpos = width_margin - fontwidth;
ypos = height_margin - fontheight;
break;
}
return new point(xpos, ypos);
}
}
}
3.配置文件的watermarkconfig.xml,内容如下:
复制代码 代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<watermark>
<allowhost>localhost:6219</allowhost><!--允许访问的域名-->
<isflag>true</isflag><!-- true、false-->
<type>font</type><!-- img、font-->
<files>/config|/upfiles/ab</files><!--需要加水印的文件夹-->
<position>bottom-right</position><!-- top-left、top-right、bottom-left、bottom-right-->
<img-path>~/upfiles/watermark.png</img-path><!-- 水印位置 -->
<font-style>1</font-style><!--普通文本 0, 加粗文本 1, 倾斜文本 2, 带下划线的文本 4, 中间有直线通过的文本 8-->
<font-size>60</font-size>
<font-color>red</font-color>
<font-content>¥:8000元</font-content>
<errimgpath>images/error.jpg</errimgpath><!-- 盗图片的请求返回的跟目录下的某图片 -->
</watermark>
上一篇: Android之ProgressBar即时显示下载进度详解
下一篇: C# 定义常量 两种实现方法