您的位置:首页 > 编程语言 > ASP

ASP.NET 图片加水印防盗链

2012-04-01 10:16 453 查看
首先建一个类:

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>

参考:

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>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: