-
C#教程之C#(.net)水印图片的生成完整实例
本文以一个完整实例讲述了C#水印图片的生成方法。是非常实用的技巧。分享给大家供大家参考。
具体实例代码如下:
1
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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
|
/* * * 使用说明: * 建议先定义一个WaterImage实例 * 然后利用实例的属性,去匹配需要进行操作的参数 * 然后定义一个WaterImageManage实例 * 利用WaterImageManage实例进行DrawImage(),印图片水印 * DrawWords()印文字水印 * */ using System; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Drawing2D; using System.IO; namespace ABC { /// <summary> /// 图片位置 /// </summary> public enum ImagePosition { LeftTop, //左上 LeftBottom, //左下 RightTop, //右上 RigthBottom, //右下 TopMiddle, //顶部居中 BottomMiddle, //底部居中 Center //中心 } /// <summary> /// 水印图片的操作管理 Design by Gary Gong From Demetersoft.com /// </summary> public class WaterImageManage { /// <summary> /// 生成一个新的水印图片制作实例 /// </summary> public WaterImageManage() { // // TODO: Add constructor logic here // } /// <summary> /// 添加图片水印 /// </summary> /// <param name="sourcePicture">源图片文件名</param> /// <param name="waterImage">水印图片文件名</param> /// <param name="alpha">透明度(0.1-1.0数值越小透明度越高)</param> /// <param name="position">位置</param> /// <param name="PicturePath" >图片的路径</param> /// <returns>返回生成于指定文件夹下的水印文件名</returns> public string DrawImage( string sourcePicture, string waterImage, float alpha, ImagePosition position, string PicturePath) { // // 判断参数是否有效 // if (sourcePicture == string .Empty || waterImage == string .Empty || alpha == 0.0 || PicturePath == string .Empty) { return sourcePicture; } // // 源图片,水印图片全路径 // string sourcePictureName = PicturePath + sourcePicture; string waterPictureName = PicturePath + waterImage; string fileSourceExtension = System.IO.Path.GetExtension(sourcePictureName).ToLower(); string fileWaterExtension = System.IO.Path.GetExtension(waterPictureName).ToLower(); // // 判断文件是否存在,以及类型是否正确 // if (System.IO.File.Exists(sourcePictureName) == false || System.IO.File.Exists(waterPictureName) == false || ( fileSourceExtension != ".gif" && fileSourceExtension != ".jpg" && fileSourceExtension != ".png" ) || ( fileWaterExtension != ".gif" && fileWaterExtension != ".jpg" && fileWaterExtension != ".png" ) ) { return sourcePicture; } // // 目标图片名称及全路径 // string targetImage = sourcePictureName.Replace(System.IO.Path.GetExtension(sourcePictureName), "" ) + "_1101.jpg" ; // // 将需要加上水印的图片装载到Image对象中 // Image imgPhoto = Image.FromFile(sourcePictureName); // // 确定其长宽 // int phWidth = imgPhoto.Width; int phHeight = imgPhoto.Height; // // 封装 GDI+ 位图,此位图由图形图像及其属性的像素数据组成。 // Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb); // // 设定分辨率 // bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution); // // 定义一个绘图画面用来装载位图 // Graphics grPhoto = Graphics.FromImage(bmPhoto); // //同样,由于水印是图片,我们也需要定义一个Image来装载它 // Image imgWatermark = new Bitmap(waterPictureName); // // 获取水印图片的高度和宽度 // int wmWidth = imgWatermark.Width; int wmHeight = imgWatermark.Height; //SmoothingMode:指定是否将平滑处理(消除锯齿)应用于直线、曲线和已填充区域的边缘。 // 成员名称 说明 // AntiAlias 指定消除锯齿的呈现。 // Default 指定不消除锯齿。 // HighQuality 指定高质量、低速度呈现。 // HighSpeed 指定高速度、低质量呈现。 // Invalid 指定一个无效模式。 // None 指定不消除锯齿。 grPhoto.SmoothingMode = SmoothingMode.AntiAlias; // // 第一次描绘,将我们的底图描绘在绘图画面上 // grPhoto.DrawImage(imgPhoto, new Rectangle(0, 0, phWidth, phHeight), 0, 0, phWidth, phHeight, GraphicsUnit.Pixel); // // 与底图一样,我们需要一个位图来装载水印图片。并设定其分辨率 // Bitmap bmWatermark = new Bitmap(bmPhoto); bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution); // // 继续,将水印图片装载到一个绘图画面grWatermark // Graphics grWatermark = Graphics.FromImage(bmWatermark); // //ImageAttributes 对象包含有关在呈现时如何操作位图和图元文件颜色的信息。 // ImageAttributes imageAttributes = new ImageAttributes(); // //Colormap: 定义转换颜色的映射 // ColorMap colorMap = new ColorMap(); // //我的水印图被定义成拥有绿色背景色的图片被替换成透明 // colorMap.OldColor = Color.FromArgb(255, 0, 255, 0); colorMap.NewColor = Color.FromArgb(0, 0, 0, 0); ColorMap[] remapTable = { colorMap }; imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap); float [][] colorMatrixElements = { new float [] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // red红色 new float [] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, //green绿色 new float [] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, //blue蓝色 new float [] {0.0f, 0.0f, 0.0f, alpha, 0.0f}, //透明度 new float [] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}}; // // ColorMatrix:定义包含 RGBA 空间坐标的 5 x 5 矩阵。 // ImageAttributes 类的若干方法通过使用颜色矩阵调整图像颜色。 ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements); imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); // //上面设置完颜色,下面开始设置位置 // int xPosOfWm; int yPosOfWm; switch (position) { case ImagePosition.BottomMiddle: xPosOfWm = (phWidth - wmWidth) / 2; yPosOfWm = phHeight - wmHeight - 10; break ; case ImagePosition.Center: xPosOfWm = (phWidth - wmWidth) / 2; yPosOfWm = (phHeight - wmHeight) / 2; break ; case ImagePosition.LeftBottom: xPosOfWm = 10; yPosOfWm = phHeight - wmHeight - 10; break ; case ImagePosition.LeftTop: xPosOfWm = 10; yPosOfWm = 10; break ; case ImagePosition.RightTop: xPosOfWm = phWidth - wmWidth - 10; yPosOfWm = 10; break ; case ImagePosition.RigthBottom: xPosOfWm = phWidth - wmWidth - 10; yPosOfWm = phHeight - wmHeight - 10; break ; case ImagePosition.TopMiddle: xPosOfWm = (phWidth - wmWidth) / 2; yPosOfWm = 10; break ; default : xPosOfWm = 10; yPosOfWm = phHeight - wmHeight - 10; break ; } // 第二次绘图,把水印印上去 // grWatermark.DrawImage(imgWatermark, new Rectangle(xPosOfWm, yPosOfWm, wmWidth, wmHeight), 0, 0, wmWidth, wmHeight, GraphicsUnit.Pixel, imageAttributes); imgPhoto = bmWatermark; grPhoto.Dispose(); grWatermark.Dispose(); // // 保存文件到服务器的文件夹里面 // imgPhoto.Save(targetImage, ImageFormat.Jpeg); imgPhoto.Dispose(); imgWatermark.Dispose(); return targetImage.Replace(PicturePath, "" ); } /* * * 使用说明: * 建议先定义一个WaterImage实例 * 然后利用实例的属性,去匹配需要进行操作的参数 * 然后定义一个WaterImageManage实例 * 利用WaterImageManage实例进行DrawImage(),印图片水印 * DrawWords()印文字水印 * -*/ /// <summary> /// 在图片上添加水印文字 /// </summary> /// <param name="sourcePicture">源图片文件(文件名,不包括路径)</param> /// <param name="waterWords">需要添加到图片上的文字</param> /// <param name="alpha">透明度</param> /// <param name="position">位置</param> /// <param name="PicturePath">文件路径</param> /// <returns></returns> public string DrawWords( string sourcePicture, string waterWords, float alpha, ImagePosition position, string PicturePath) { // // 判断参数是否有效 // if (sourcePicture == string .Empty || waterWords == string .Empty || alpha == 0.0 || PicturePath == string .Empty) { return sourcePicture; } // // 源图片全路径 // if (PicturePath.Substring(PicturePath.Length - 1, 1) != "/" ) PicturePath += "/" ; string sourcePictureName = PicturePath + sourcePicture; string fileExtension = System.IO.Path.GetExtension(sourcePictureName).ToLower(); // // 判断文件是否存在,以及文件名是否正确 // if (System.IO.File.Exists(sourcePictureName) == false || ( fileExtension != ".gif" && fileExtension != ".jpg" && fileExtension != ".png" )) { return sourcePicture; } // // 目标图片名称及全路径 // string targetImage = sourcePictureName.Replace(System.IO.Path.GetExtension(sourcePictureName), "" ) + "_0703.jpg" ; //创建一个图片对象用来装载要被添加水印的图片 Image imgPhoto = Image.FromFile(sourcePictureName); //获取图片的宽和高 int phWidth = imgPhoto.Width; int phHeight = imgPhoto.Height; // //建立一个bitmap,和我们需要加水印的图片一样大小 Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb); //SetResolution:设置此 Bitmap 的分辨率 //这里直接将我们需要添加水印的图片的分辨率赋给了bitmap bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution); //Graphics:封装一个 GDI+ 绘图图面。 Graphics grPhoto = Graphics.FromImage(bmPhoto); //设置图形的品质 grPhoto.SmoothingMode = SmoothingMode.AntiAlias; //将我们要添加水印的图片按照原始大小描绘(复制)到图形中 grPhoto.DrawImage( imgPhoto, // 要添加水印的图片 new Rectangle(0, 0, phWidth, phHeight), // 根据要添加的水印图片的宽和高 0, // X方向从0点开始描绘 0, // Y方向 phWidth, // X方向描绘长度 phHeight, // Y方向描绘长度 GraphicsUnit.Pixel); // 描绘的单位,这里用的是像素 //根据图片的大小我们来确定添加上去的文字的大小 //在这里我们定义一个数组来确定 int [] sizes = new int [] { 16, 14, 12, 10, 8, 6, 4 }; //字体 Font crFont = null ; //矩形的宽度和高度,SizeF有三个属性,分别为Height高,width宽,IsEmpty是否为空 SizeF crSize = new SizeF(); //利用一个循环语句来选择我们要添加文字的型号 //直到它的长度比图片的宽度小 for ( int i = 0; i < 7; i++) { crFont = new Font( "arial" , sizes[i], FontStyle.Bold); //测量用指定的 Font 对象绘制并用指定的 StringFormat 对象格式化的指定字符串。 crSize = grPhoto.MeasureString(waterWords, crFont); // ushort 关键字表示一种整数数据类型 if (( ushort )crSize.Width < ( ushort )phWidth) break ; } //截边5%的距离,定义文字显示(由于不同的图片显示的高和宽不同,所以按百分比截取) int yPixlesFromBottom = ( int )(phHeight * .05); //定义在图片上文字的位置 float wmHeight = crSize.Height; float wmWidth = crSize.Width; float xPosOfWm; float yPosOfWm; switch (position) { case ImagePosition.BottomMiddle: xPosOfWm = phWidth / 2; yPosOfWm = phHeight - wmHeight - 10; break ; case ImagePosition.Center: xPosOfWm = phWidth / 2; yPosOfWm = phHeight / 2; break ; case ImagePosition.LeftBottom: xPosOfWm = wmWidth; yPosOfWm = phHeight - wmHeight - 10; break ; case ImagePosition.LeftTop: xPosOfWm = wmWidth / 2; yPosOfWm = wmHeight / 2; break ; case ImagePosition.RightTop: xPosOfWm = phWidth - wmWidth - 10; yPosOfWm = wmHeight; break ; case ImagePosition.RigthBottom: xPosOfWm = phWidth - wmWidth - 10; yPosOfWm = phHeight - wmHeight - 10; break ; case ImagePosition.TopMiddle: xPosOfWm = phWidth / 2; yPosOfWm = wmWidth; break ; default : xPosOfWm = wmWidth; yPosOfWm = phHeight - wmHeight - 10; break ; } //封装文本布局信息(如对齐、文字方向和 Tab 停靠位),显示操作(如省略号插入和国家标准 (National) 数字替换)和 OpenType 功能。 StringFormat StrFormat = new StringFormat(); //定义需要印的文字居中对齐 StrFormat.Alignment = StringAlignment.Center; //SolidBrush:定义单色画笔。画笔用于填充图形形状,如矩形、椭圆、扇形、多边形和封闭路径。 //这个画笔为描绘阴影的画笔,呈灰色 int m_alpha = Convert.ToInt32(256 * alpha); SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(m_alpha, 0, 0, 0)); //描绘文字信息,这个图层向右和向下偏移一个像素,表示阴影效果 //DrawString 在指定矩形并且用指定的 Brush 和 Font 对象绘制指定的文本字符串。 grPhoto.DrawString(waterWords, //string of text crFont, //font semiTransBrush2, //Brush new PointF(xPosOfWm + 1, yPosOfWm + 1), //Position StrFormat); //从四个 ARGB 分量(alpha、红色、绿色和蓝色)值创建 Color 结构,这里设置透明度为153 //这个画笔为描绘正式文字的笔刷,呈白色 SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255)); //第二次绘制这个图形,建立在第一次描绘的基础上 grPhoto.DrawString(waterWords, //string of text crFont, //font semiTransBrush, //Brush new PointF(xPosOfWm, yPosOfWm), //Position StrFormat); //imgPhoto是我们建立的用来装载最终图形的Image对象 //bmPhoto是我们用来制作图形的容器,为Bitmap对象 imgPhoto = bmPhoto; //释放资源,将定义的Graphics实例grPhoto释放,grPhoto功德圆满 grPhoto.Dispose(); //将grPhoto保存 imgPhoto.Save(targetImage, ImageFormat.Jpeg); imgPhoto.Dispose(); return targetImage.Replace(PicturePath, "" ); } } /// <summary> /// 装载水印图片的相关信息 /// </summary> public class WaterImage { public WaterImage() { } private string m_sourcePicture; /// <summary> /// 源图片地址名字(带后缀) /// </summary> public string SourcePicture { get { return m_sourcePicture; } set { m_sourcePicture = value; } } private string m_waterImager; /// <summary> /// 水印图片名字(带后缀) /// </summary> public string WaterPicture { get { return m_waterImager; } set { m_waterImager = value; } } private float m_alpha; /// <summary> /// 水印图片文字的透明度 /// </summary> public float Alpha { get { return m_alpha; } set { m_alpha = value; } } private ImagePosition m_postition; /// <summary> /// 水印图片或文字在图片中的位置 /// </summary> public ImagePosition Position { get { return m_postition; } set { m_postition = value; } } private string m_words; /// <summary> /// 水印文字的内容 /// </summary> public string Words { get { return m_words; } set { m_words = value; } } } } |
相信本文所述对大家的C#程序设计有一定的借鉴参考作用。
栏目列表
最新更新
python爬虫及其可视化
使用python爬取豆瓣电影短评评论内容
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比