这两天主要在学习如何给图片添加水印,查找了一下相关的解决方案,其中有一个别人写好的水印dll,虽然能实现很多的功能,但很遗憾不能用于其他商业用途,没办法只能再找找别的办法,后面找到的这种方法比较简单,就是通过Graphics重新绘制bitmap的方法来绘制水印,当然,文字水印可能稍微要麻烦一点儿,需要设置字体相关的东东,比如字号、阴影、颜色啥的,但整体来看,思路基本是一样的。
至于具体的步骤说明,请查看源码上的注释即可,应该能够保证大家不至于太迷糊:
第一部分:水印相关参数结构体和枚举
View Code
1 /// <summary>
2 /// 水印位置枚举
3 /// </summary>
4 public enum ImagePosition
5 {
6 LeftTop, //左上
7 LeftBottom, //左下
8 RightTop, //右上
9 RigthBottom, //右下
10 TopMiddle, //顶部居中
11 BottomMiddle, //底部居中
12 Center //中心
13 }
14
15 /// <summary>
16 /// 图片水印参数结构体
17 /// </summary>
18 public struct ImageWatermarkParameters
19 {
20 /// <summary>
21 /// 源图片路径
22 /// </summary>
23 public string SourceImagePath;
24 /// <summary>
25 /// 水印图片路径
26 /// </summary>
27 public string WatermarkImagePath;
28 /// <summary>
29 /// 源图片数据流(即如果设置数据流,则忽略SourceImagePath属性值)
30 /// </summary>
31 public MemoryStream SourceImageStream;
32 /// <summary>
33 /// 水印图片数据流(即如果设置数据流,则忽略WatermarkImagePath属性值)
34 /// </summary>
35 public MemoryStream WatermarkImageStream;
36 /// <summary>
37 /// 透明度,数值介于0.1 - 1.0之间,不包括0.0
38 /// </summary>
39 public float Alpha;
40 /// <summary>
41 /// 水印位置
42 /// </summary>
43 public ImagePosition WmPosition;
44 private string _sourceImageFileExtensionName;
45 /// <summary>
46 /// 源图片文件扩展名
47 /// </summary>
48 public string SourceImageFileExtensionName
49 {
50 set { _sourceImageFileExtensionName = value; }
51 get
52 {
53 if (string.IsNullOrEmpty(this.SourceImagePath))
54 {
55 // 如果设置的图片扩展名为ContentType类型,则进行转化
56 if (_sourceImageFileExtensionName.IndexOf("/") > 0)
57 _sourceImageFileExtensionName = TransferContentTypeToUnifyExName(_sourceImageFileExtensionName);
58
59 return _sourceImageFileExtensionName;
60 }
61 else
62 return Path.GetExtension(SourceImagePath).ToLower();
63 }
64 }
65
66
67 public ImageWatermarkParameters(string sourceImagePath, string watermarkImagePath, float alpha, ImagePosition wmPosition)
68 {
69 this.SourceImageStream = null;
70 this.WatermarkImageStream = null;
71 this._sourceImageFileExtensionName = string.Empty;
72
73 this.SourceImagePath = sourceImagePath;
74 this.WatermarkImagePath = watermarkImagePath;
75 this.Alpha = alpha;
76 this.WmPosition = wmPosition;
77 }
78
79 public ImageWatermarkParameters(MemoryStream sourceImageStream, MemoryStream watermarkImageStream,
80 string sourceImageFileExtensionName, float alpha, ImagePosition wmPosition)
81 {
82 this.SourceImagePath = string.Empty;
83 this.WatermarkImagePath = string.Empty; ;
84
85 this.SourceImageStream = sourceImageStream;
86 this.WatermarkImageStream = watermarkImageStream;
87 this.Alpha = alpha;
88 this.WmPosition = wmPosition;
89 this._sourceImageFileExtensionName = sourceImageFileExtensionName;
90 }
91
92 /// <summary>
93 /// 参数检查并设定默认值
94 /// </summary>
95 /// <param name="errorMsg"></param>
96 /// <returns></returns>
97 public bool CheckAndSetDefault(out string errorMsg)
98 {
99 errorMsg = string.Empty;
100
101 // 前置检查
102 if ((string.IsNullOrEmpty(this.SourceImagePath) && SourceImageStream == null)
103 || (string.IsNullOrEmpty(this.WatermarkImagePath) && WatermarkImageStream == null)
104 || (SourceImageStream != null && string.IsNullOrEmpty(_sourceImageFileExtensionName))
105 || this.Alpha <= 0.0 || this.Alpha > 1.0
106 || this.WmPosition == null)
107 {
108 errorMsg = "文字水印参数实体中含有非法的参数项。";
109 return false;
110 }
111
112 // 检查图片路径是否合法
113 if ((SourceImageStream == null && !string.IsNullOrEmpty(this.SourceImagePath) && !File.Exists(this.SourceImagePath)) // 仅赋值源图片路径,且路径不存在的情况
114 || (WatermarkImageStream == null && !string.IsNullOrEmpty(this.WatermarkImagePath) && !File.Exists(this.WatermarkImagePath))) // 仅赋值水印图片路径,但文件不存在的情况
115 {
116 errorMsg = "输入的源图片或水印图片路径不存在。";
117 return false;
118 }
119
120
121 // 检查图片扩展名
122 bool validExName = true;
123 if (!string.IsNullOrEmpty(this.SourceImagePath) && !string.IsNullOrEmpty(this.WatermarkImagePath))
124 {
125 if (!CheckImageExtensionType(this.SourceImagePath) || !CheckImageExtensionType(this.WatermarkImagePath))
126 validExName = false;
127 }
128 else if (this.SourceImageStream != null && this.WatermarkImageStream != null)
129 {
130 if ((_sourceImageFileExtensionName != ".gif" && _sourceImageFileExtensionName != ".jpg" && _sourceImageFileExtensionName != ".png"))
131 validExName = false;
132 }
133 else
134 validExName = false;
135
136 if (!validExName)
137 {
138 errorMsg = "暂不支持源图片或水印图片的格式类型。";
139 return false;
140 }
141
142 return true;
143 }
144 }
145
146 /// <summary>
147 /// 文字水印参数结构体
148 /// </summary>
149 public struct TextWatermarkParameters
150 {
151 /// <summary>
152 /// 源图片路径
153 /// </summary>
154 public string SourceImagePath;
155 /// <summary>
156 /// 水印文字
157 /// </summary>
158 public string WatermarkText;
159 /// <summary>
160 /// 源图片数据流
161 /// </summary>
162 public MemoryStream SourceImageStream;
163 /// <summary>
164 /// 透明度,数值介于0.1 - 1.0之间,不包括0.0
165 /// </summary>
166 public float Alpha;
167 /// <summary>
168 /// 水印位置
169 /// </summary>
170 public ImagePosition WmPosition;
171 /// <summary>
172 /// 水印文字字体样式
173 /// </summary>
174 public Font WmTextFont;
175 /// <summary>
176 /// 水印文字阴影宽度
177 /// </summary>
178 public int TextShadowWidth;
179 private string _sourceImageFileExtensionName;
180 /// <summary>
181 /// 源图片文件扩展名
182 /// </summary>
183 public string SourceImageFileExtensionName
184 {
185 set { _sourceImageFileExtensionName = value; }
186 get
187 {
188 if (string.IsNullOrEmpty(this.SourceImagePath))
189 {
190 // 如果设置的图片扩展名为ContentType类型,则进行转化
191 if (_sourceImageFileExtensionName.IndexOf("/") > 0)
192 _sourceImageFileExtensionName = TransferContentTypeToUnifyExName(_sourceImageFileExtensionName);
193
194 return _sourceImageFileExtensionName;
195 }
196 else
197 return Path.GetExtension(SourceImagePath).ToLower();
198 }
199 }
200
201
202 public TextWatermarkParameters(MemoryStream sourceImageStream, string sourceImageFileExtensionName, string watermarkText, float alpha,
203 ImagePosition wmPosition, Font wmTextFont, int textShadowWidth = 5)
204 {
205 this.SourceImagePath = string.Empty ;
206
207 this.SourceImageStream = sourceImageStream;
208 this.WatermarkText = watermarkText;
209 this.Alpha = alpha;
210 this.WmPosition = wmPosition;
211 this.WmTextFont = wmTextFont;
212 this.TextShadowWidth = textShadowWidth;
213 this._sourceImageFileExtensionName = sourceImageFileExtensionName;
214 }
215
216 public TextWatermarkParameters(string sourceImagePath, string watermarkText, float alpha,
217 ImagePosition wmPosition, Font wmTextFont, int textShadowWidth = 5)
218 {
219 this.SourceImageStream = null;
220 this._sourceImageFileExtensionName = string.Empty;
221
222 this.SourceImagePath = sourceImagePath;
223 this.WatermarkText = watermarkText;
224 this.Alpha = alpha;
225 this.WmPosition = wmPosition;
226 this.WmTextFont = wmTextFont;
227 this.TextShadowWidth = textShadowWidth;
228 }
229
230 /// <summary>
231 /// 参数检查并设定默认值
232 /// </summary>
233 /// <param name="errorMsg"></param>
234 /// <returns></returns>
235 public bool CheckAndSetDefault(out string errorMsg)
236 {
237 errorMsg = string.Empty;
238
239 // 前置检查
240 if ((string.IsNullOrEmpty(this.SourceImagePath) && this.SourceImageStream == null) || (!string.IsNullOrEmpty(this.SourceImagePath) && !File.Exists(this.SourceImagePath))
241 || string.IsNullOrEmpty(this.WatermarkText)
242 || (SourceImageStream != null && string.IsNullOrEmpty(_sourceImageFileExtensionName))
243 || this.Alpha <= 0.0 || this.Alpha > 1.0
244 || this.WmPosition == null
245 || this.WmTextFont == null)
246 {
247 errorMsg = "文字水印参数实体中含有非法的参数项。";
248 return false;
249 }
250
251 // 检查图片路径是否合法
252 if ((SourceImageStream == null && !string.IsNullOrEmpty(this.SourceImagePath) && !File.Exists(this.SourceImagePath))) // 仅赋值源图片路径,且路径不存在的情况
253 {
254 errorMsg = "输入的源图片路径不存在。";
255 return false;
256 }
257
258 // 检查图片扩展名
259 bool validExName = true;
260 if (!string.IsNullOrEmpty(this.SourceImagePath))
261 {
262 if (!CheckImageExtensionType(this.SourceImagePath))
263 validExName = false;
264 }
265 else if (this.SourceImageStream != null)
266 {
267 if ((_sourceImageFileExtensionName != ".gif" && _sourceImageFileExtensionName != ".jpg" && _sourceImageFileExtensionName != ".png"))
268 validExName = false;
269 }
270 else
271 validExName = false;
272
273 if (!validExName)
274 {
275 errorMsg = "暂不支持源图片的格式类型。";
276 return false;
277 }
278
279 return true;
280 }
281
2 /// 水印位置枚举
3 /// </summary>
4 public enum ImagePosition
5 {
6 LeftTop, //左上
7 LeftBottom, //左下
8 RightTop, //右上
9 RigthBottom, //右下
10 TopMiddle, //顶部居中
11 BottomMiddle, //底部居中
12 Center //中心
13 }
14
15 /// <summary>
16 /// 图片水印参数结构体
17 /// </summary>
18 public struct ImageWatermarkParameters
19 {
20 /// <summary>
21 /// 源图片路径
22 /// </summary>
23 public string SourceImagePath;
24 /// <summary>
25 /// 水印图片路径
26 /// </summary>
27 public string WatermarkImagePath;
28 /// <summary>
29 /// 源图片数据流(即如果设置数据流,则忽略SourceImagePath属性值)
30 /// </summary>
31 public MemoryStream SourceImageStream;
32 /// <summary>
33 /// 水印图片数据流(即如果设置数据流,则忽略WatermarkImagePath属性值)
34 /// </summary>
35 public MemoryStream WatermarkImageStream;
36 /// <summary>
37 /// 透明度,数值介于0.1 - 1.0之间,不包括0.0
38 /// </summary>
39 public float Alpha;
40 /// <summary>
41 /// 水印位置
42 /// </summary>
43 public ImagePosition WmPosition;
44 private string _sourceImageFileExtensionName;
45 /// <summary>
46 /// 源图片文件扩展名
47 /// </summary>
48 public string SourceImageFileExtensionName
49 {
50 set { _sourceImageFileExtensionName = value; }
51 get
52 {
53 if (string.IsNullOrEmpty(this.SourceImagePath))
54 {
55 // 如果设置的图片扩展名为ContentType类型,则进行转化
56 if (_sourceImageFileExtensionName.IndexOf("/") > 0)
57 _sourceImageFileExtensionName = TransferContentTypeToUnifyExName(_sourceImageFileExtensionName);
58
59 return _sourceImageFileExtensionName;
60 }
61 else
62 return Path.GetExtension(SourceImagePath).ToLower();
63 }
64 }
65
66
67 public ImageWatermarkParameters(string sourceImagePath, string watermarkImagePath, float alpha, ImagePosition wmPosition)
68 {
69 this.SourceImageStream = null;
70 this.WatermarkImageStream = null;
71 this._sourceImageFileExtensionName = string.Empty;
72
73 this.SourceImagePath = sourceImagePath;
74 this.WatermarkImagePath = watermarkImagePath;
75 this.Alpha = alpha;
76 this.WmPosition = wmPosition;
77 }
78
79 public ImageWatermarkParameters(MemoryStream sourceImageStream, MemoryStream watermarkImageStream,
80 string sourceImageFileExtensionName, float alpha, ImagePosition wmPosition)
81 {
82 this.SourceImagePath = string.Empty;
83 this.WatermarkImagePath = string.Empty; ;
84
85 this.SourceImageStream = sourceImageStream;
86 this.WatermarkImageStream = watermarkImageStream;
87 this.Alpha = alpha;
88 this.WmPosition = wmPosition;
89 this._sourceImageFileExtensionName = sourceImageFileExtensionName;
90 }
91
92 /// <summary>
93 /// 参数检查并设定默认值
94 /// </summary>
95 /// <param name="errorMsg"></param>
96 /// <returns></returns>
97 public bool CheckAndSetDefault(out string errorMsg)
98 {
99 errorMsg = string.Empty;
100
101 // 前置检查
102 if ((string.IsNullOrEmpty(this.SourceImagePath) && SourceImageStream == null)
103 || (string.IsNullOrEmpty(this.WatermarkImagePath) && WatermarkImageStream == null)
104 || (SourceImageStream != null && string.IsNullOrEmpty(_sourceImageFileExtensionName))
105 || this.Alpha <= 0.0 || this.Alpha > 1.0
106 || this.WmPosition == null)
107 {
108 errorMsg = "文字水印参数实体中含有非法的参数项。";
109 return false;
110 }
111
112 // 检查图片路径是否合法
113 if ((SourceImageStream == null && !string.IsNullOrEmpty(this.SourceImagePath) && !File.Exists(this.SourceImagePath)) // 仅赋值源图片路径,且路径不存在的情况
114 || (WatermarkImageStream == null && !string.IsNullOrEmpty(this.WatermarkImagePath) && !File.Exists(this.WatermarkImagePath))) // 仅赋值水印图片路径,但文件不存在的情况
115 {
116 errorMsg = "输入的源图片或水印图片路径不存在。";
117 return false;
118 }
119
120
121 // 检查图片扩展名
122 bool validExName = true;
123 if (!string.IsNullOrEmpty(this.SourceImagePath) && !string.IsNullOrEmpty(this.WatermarkImagePath))
124 {
125 if (!CheckImageExtensionType(this.SourceImagePath) || !CheckImageExtensionType(this.WatermarkImagePath))
126 validExName = false;
127 }
128 else if (this.SourceImageStream != null && this.WatermarkImageStream != null)
129 {
130 if ((_sourceImageFileExtensionName != ".gif" && _sourceImageFileExtensionName != ".jpg" && _sourceImageFileExtensionName != ".png"))
131 validExName = false;
132 }
133 else
134 validExName = false;
135
136 if (!validExName)
137 {
138 errorMsg = "暂不支持源图片或水印图片的格式类型。";
139 return false;
140 }
141
142 return true;
143 }
144 }
145
146 /// <summary>
147 /// 文字水印参数结构体
148 /// </summary>
149 public struct TextWatermarkParameters
150 {
151 /// <summary>
152 /// 源图片路径
153 /// </summary>
154 public string SourceImagePath;
155 /// <summary>
156 /// 水印文字
157 /// </summary>
158 public string WatermarkText;
159 /// <summary>
160 /// 源图片数据流
161 /// </summary>
162 public MemoryStream SourceImageStream;
163 /// <summary>
164 /// 透明度,数值介于0.1 - 1.0之间,不包括0.0
165 /// </summary>
166 public float Alpha;
167 /// <summary>
168 /// 水印位置
169 /// </summary>
170 public ImagePosition WmPosition;
171 /// <summary>
172 /// 水印文字字体样式
173 /// </summary>
174 public Font WmTextFont;
175 /// <summary>
176 /// 水印文字阴影宽度
177 /// </summary>
178 public int TextShadowWidth;
179 private string _sourceImageFileExtensionName;
180 /// <summary>
181 /// 源图片文件扩展名
182 /// </summary>
183 public string SourceImageFileExtensionName
184 {
185 set { _sourceImageFileExtensionName = value; }
186 get
187 {
188 if (string.IsNullOrEmpty(this.SourceImagePath))
189 {
190 // 如果设置的图片扩展名为ContentType类型,则进行转化
191 if (_sourceImageFileExtensionName.IndexOf("/") > 0)
192 _sourceImageFileExtensionName = TransferContentTypeToUnifyExName(_sourceImageFileExtensionName);
193
194 return _sourceImageFileExtensionName;
195 }
196 else
197 return Path.GetExtension(SourceImagePath).ToLower();
198 }
199 }
200
201
202 public TextWatermarkParameters(MemoryStream sourceImageStream, string sourceImageFileExtensionName, string watermarkText, float alpha,
203 ImagePosition wmPosition, Font wmTextFont, int textShadowWidth = 5)
204 {
205 this.SourceImagePath = string.Empty ;
206
207 this.SourceImageStream = sourceImageStream;
208 this.WatermarkText = watermarkText;
209 this.Alpha = alpha;
210 this.WmPosition = wmPosition;
211 this.WmTextFont = wmTextFont;
212 this.TextShadowWidth = textShadowWidth;
213 this._sourceImageFileExtensionName = sourceImageFileExtensionName;
214 }
215
216 public TextWatermarkParameters(string sourceImagePath, string watermarkText, float alpha,
217 ImagePosition wmPosition, Font wmTextFont, int textShadowWidth = 5)
218 {
219 this.SourceImageStream = null;
220 this._sourceImageFileExtensionName = string.Empty;
221
222 this.SourceImagePath = sourceImagePath;
223 this.WatermarkText = watermarkText;
224 this.Alpha = alpha;
225 this.WmPosition = wmPosition;
226 this.WmTextFont = wmTextFont;
227 this.TextShadowWidth = textShadowWidth;
228 }
229
230 /// <summary>
231 /// 参数检查并设定默认值
232 /// </summary>
233 /// <param name="errorMsg"></param>
234 /// <returns></returns>
235 public bool CheckAndSetDefault(out string errorMsg)
236 {
237 errorMsg = string.Empty;
238
239 // 前置检查
240 if ((string.IsNullOrEmpty(this.SourceImagePath) && this.SourceImageStream == null) || (!string.IsNullOrEmpty(this.SourceImagePath) && !File.Exists(this.SourceImagePath))
241 || string.IsNullOrEmpty(this.WatermarkText)
242 || (SourceImageStream != null && string.IsNullOrEmpty(_sourceImageFileExtensionName))
243 || this.Alpha <= 0.0 || this.Alpha > 1.0
244 || this.WmPosition == null
245 || this.WmTextFont == null)
246 {
247 errorMsg = "文字水印参数实体中含有非法的参数项。";
248 return false;
249 }
250
251 // 检查图片路径是否合法
252 if ((SourceImageStream == null && !string.IsNullOrEmpty(this.SourceImagePath) && !File.Exists(this.SourceImagePath))) // 仅赋值源图片路径,且路径不存在的情况
253 {
254 errorMsg = "输入的源图片路径不存在。";
255 return false;
256 }
257
258 // 检查图片扩展名
259 bool validExName = true;
260 if (!string.IsNullOrEmpty(this.SourceImagePath))
261 {
262 if (!CheckImageExtensionType(this.SourceImagePath))
263 validExName = false;
264 }
265 else if (this.SourceImageStream != null)
266 {
267 if ((_sourceImageFileExtensionName != ".gif" && _sourceImageFileExtensionName != ".jpg" && _sourceImageFileExtensionName != ".png"))
268 validExName = false;
269 }
270 else
271 validExName = false;
272
273 if (!validExName)
274 {
275 errorMsg = "暂不支持源图片的格式类型。";
276 return false;
277 }
278
279 return true;
280 }
281
第二部分:水印功能处理类 -> 内部辅助函数部分
View Code
return exName;