利用.net中System.Drawing命名空间下的常用类我们就可以轻松的为图片添加文字水印和图片水印,并且可以自定义水印文字和水印图片的大小、位置、颜色、透明度等等!对于jpg或者png等图片,可以直接通过Graphics g= Graphics.FromImage(image)来获得Graphics对象,但对于gif图片,通过这种方法无法获得Graphics对象,解决这个问题的方法是首先根据.gif文件的大小生成一个位图作图区,然后将原图复制到作图区,做进行处理,以下是水印添加类的完整代码:
1
using System;
2
using System.Drawing;
3
using System.Drawing.Imaging;
4
using System.IO;
5
using System.Drawing.Drawing2D;
6
7
namespace JillZhang
8
{
9
/// <summary>
10
/// 给图片添加水印得类得描述
11
/// </summary>
12
public class WaterMark
13
{
14
private bool _textMark=false;
15
private bool _imgMark=false;
16
private string _text="";
17
private string _imgPath="";
18
private int _markX=0;
19
private int _markY=0;
20
private float _transparency=1;
21
private string _fontFamily="宋体";
22
private Color _textColor=Color.Black;
23
private bool _textbold=false;
24
int[] sizes=new int[]{48,32,16,8,6,4};
25
/// <summary>
26
/// 实例化一个水印类
27
/// </summary>
28
public WaterMark()
29
{
30
31
}
32
/// <summary>
33
/// 初始化一个只添加文字水印得实例
34
/// </summary>
35
/// <param name="text">水印文字</param>
36
/// <param name="fontFamily">文字字体</param>
37
/// <param name="bold">是否粗体</param>
38
/// <param name="color">字体颜色</param>
39
/// <param name="markX">标记位置横坐标</param>
40
/// <param name="markY">标记位置纵坐标</param>
41
public WaterMark(string text,string fontFamily,bool bold,Color color,int markX,int markY)
42
{
43
this._imgMark=false;
44
this._textMark=true;
45
this._text=text;
46
this._fontFamily=fontFamily;
47
this._textbold=bold;
48
this._textColor=color;
49
this._markX=markX;
50
this._markY=MarkY;
51
}
52
/// <summary>
53
/// 实例化一个只添加图片水印得实例
54
/// </summary>
55
/// <param name="imagePath">水印图片路径</param>
56
/// <param name="tranparence">透明度</param>
57
/// <param name="markX">标记位置横坐标</param>
58
/// <param name="markY">标记位置纵坐标</param>
59
public WaterMark(string imagePath,float tranparence,int markX,int markY)
60
{
61
this._textMark=false;
62
this._imgMark=true;
63
this._imgPath=imagePath;
64
this._markX=markX;
65
this._markY=MarkY;
66
this._transparency=tranparence;
67
}
68
/// <summary>
69
/// 是否添加文字水印
70
/// </summary>
71
public bool TextMark
72
{
73
get{return _textMark;}
74
set{_textMark=value;}
75
}
76
/// <summary>
77
/// 是否添加图片水印
78
/// </summary>
79
public bool ImageMark
80
{
81
get{return _imgMark;}
82
set{_imgMark=value;}
83
}
84
/// <summary>
85
/// 文字水印得内容
86
/// </summary>
87
public string Text
88
{
89
get{return _text;}
90
set{_text=value;}
91
}
92
/// <summary>
93
/// 图片水印得图片地址
94
/// </summary>
95
public string ImagePath
96
{
97
get{return _imgPath;}
98
set{_imgPath=value;}
99
}
100
/// <summary>
101
/// 添加水印位置得横坐标
102
/// </summary>
103
public int MarkX
104
{
105
get{return _markX;}
106
set{_markX=value;}
107
}
108
/// <summary>
109
/// 添加水印位置得纵坐标
110
/// </summary>
111
public int MarkY
112
{
113
get{return _markY;}
114
set{_markY=value;}
115
}
116
/// <summary>
117
/// 水印得透明度
118
/// </summary>
119
public float Transparency
120
{
121
get{
122
if(_transparency>1.0f)
123
{
124
_transparency=1.0f;
125
}
126
return _transparency;}
127
set{_transparency=value;}
128
}
129
/// <summary>
130
/// 水印文字得颜色
131
/// </summary>
132
public Color TextColor
133
{
134
get{return _textColor;}
135
set{_textColor=value;}
136
}
137
/// <summary>
138
/// 水印文字得字体
139
/// </summary>
140
public string TextFontFamily
141
{
142
get{return _fontFamily;}
143
set{_fontFamily=value;}
144
}
145
/// <summary>
146
/// 水印文字是否加粗
147
/// </summary>
148
public bool Bold
149
{
150
get{return _textbold;}
151
set{_textbold=value;}
152
}
153
/// <summary>
154
/// 添加水印,此方法适用于gif格式得图片
155
/// </summary>
156
/// <param name="image">需要添加水印得图片</param>
157
/// <returns>添加水印之后得图片</returns>
158
public Image Mark(Image img)
159
{
160
try
161
{
162
//添加文字水印
163
if(this.TextMark)
164
{
165
//根据源图片生成新的Bitmap对象作为作图区,为了给gif图片添加水印,才有此周折
166
Bitmap newBitmap=new Bitmap(img.Width,img.Height,PixelFormat.Format24bppRgb);
167
//设置新建位图得分辨率
168
newBitmap.SetResolution(img.HorizontalResolution,img.VerticalResolution);
169
//创建Graphics对象,以对该位图进行操作
170
Graphics g = Graphics.FromImage(newBitmap);
171
//消除锯齿
172
g.SmoothingMode=SmoothingMode.AntiAlias;
173
//将原图拷贝到作图区
174
g.DrawImage(img,new Rectangle(0,0,img.Width,img.Height),0,0,img.Width,img.Height,GraphicsUnit.Pixel);
175
//声明字体对象
176
Font cFont = null;
177
//用来测试水印文本长度得尺子
178
SizeF size=new SizeF();
179
//探测出一个适合图片大小得字体大小,以适应水印文字大小得自适应
180
for(int i=0;i<6;i++)
181
{
182
//创建一个字体对象
183
cFont= new Font(this.TextFontFamily,sizes[i]);
184
//是否加粗
185
if(!this.Bold)
186
{
187
cFont= new Font(this.TextFontFamily,sizes[i],FontStyle.Regular);
188
}
189
else
190
{
191
cFont=new Font(this.TextFontFamily,sizes[i],FontStyle.Bold);
192
}
193
//测量文本大小
194
size=g.MeasureString(this.Text,cFont);
195
//匹配第一个符合要求得字体大小
196
if((ushort)size.Width<(ushort)img.Width)
197
{
198
break;
199
}
200
}
201
//创建刷子对象,准备给图片写上文字
202
Brush brush= new SolidBrush(this.TextColor);
203
//在指定得位置写上文字
204
g.DrawString(this.Text,cFont,brush,this.MarkX,this.MarkY);
205
//释放Graphics对象
206
g.Dispose();
207
//将生成得图片读入MemoryStream
208
System.IO.MemoryStream ms = new System.IO.MemoryStream();
209
newBitmap.Save(ms,ImageFormat.Jpeg);
210
//重新生成Image对象
211
img=System.Drawing.Image.FromStream(ms);
212
//返回新的Image对象
213
return img;
214
215
}
216
//添加图像水印
217
if(this.ImageMark)
218
{
219
//获得水印图像
220
Image markImg = Image.FromFile(this.ImagePath);
221
//创建颜色矩阵
222
float[][] ptsArray ={
223
new float[] {1, 0, 0, 0, 0},
224
new float[] {0, 1, 0, 0, 0},
225
new float[] {0, 0, 1, 0, 0},
226
new float[] {0, 0, 0, this.Transparency, 0}, //注意:此处为0.0f为完全透明,1.0f为完全不透明
227
new float[] {0, 0, 0, 0, 1}};
228
ColorMatrix colorMatrix= new ColorMatrix(ptsArray);
229
//新建一个Image属性
230
ImageAttributes imageAttributes= new ImageAttributes();
231
//将颜色矩阵添加到属性
232
imageAttributes.SetColorMatrix(colorMatrix,ColorMatrixFlag.Default,
233
ColorAdjustType.Default);
234
//生成位图作图区
235
Bitmap newBitmap=new Bitmap(img.Width,img.Height,PixelFormat.Format24bppRgb);
236
//设置分辨率
237
newBitmap.SetResolution(img.HorizontalResolution,img.VerticalResolution);
238
//创建Graphics
239
Graphics g = Graphics.FromImage(newBitmap);
240
//消除锯齿
241
g.SmoothingMode=SmoothingMode.AntiAlias;
242
//拷贝原图到作图区
243
g.DrawImage(img,new Rectangle(0,0,img.Width,img.Height),0,0,img.Width,img.Height,GraphicsUnit.Pixel);
244
//如果原图过小
245
if(markImg.Width>img.Width||markImg.Height>img.Height)
246
{
247
System.Drawing.Image.GetThumbnailImageAbort callb=null;
248
//对水印图片生成缩略图,缩小到原图得1/4
249
System.Drawing.Image new_img=markImg.GetThumbnailImage(img.Width/4,markImg.Height*img.Width/markImg.Width,callb,new System.IntPtr());
250
//添加水印
251
g.DrawImage(new_img,new Rectangle(this.MarkX,this.MarkY,new_img.Width,new_img.Height),0,0,new_img.Width,new_img.Height,GraphicsUnit.Pixel,imageAttributes);
252
//释放缩略图
253
new_img.Dispose();
254
//释放Graphics
255
g.Dispose();
256
//将生成得图片读入MemoryStream
257
System.IO.MemoryStream ms = new System.IO.MemoryStream();
258
newBitmap.Save(ms,ImageFormat.Jpeg);
259
//返回新的Image对象
260
img=Image.FromStream(ms);
261
return img;
262
}
263
//原图足够大
264
else
265
{
266
//添加水印
267
g.DrawImage(markImg,new Rectangle(this.MarkX,this.MarkY,markImg.Width,markImg.Height),0,0,markImg.Width,markImg.Height,GraphicsUnit.Pixel,imageAttributes);
268
//释放Graphics
269
g.Dispose();
270
//将生成得图片读入MemoryStream
271
System.IO.MemoryStream ms = new System.IO.MemoryStream();
272
newBitmap.Save(ms,ImageFormat.Jpeg);
273
//返回新的Image对象
274
img=Image.FromStream(ms);
275
return img;
276
}
277
}
278
return img;
279
}
280
catch
281
{
282
return img;
283
}
284
}
285
286
}
287
}
288
289
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
通过该类,您可以轻松的对图片加水印,但也有不足,通过这种方法添加水印,会破坏.gif动画,因为我目前还不知道如何判断.gif文件是否是动画,这个问题还需要各位网友的建议和帮助