且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能

更新时间:2022-08-12 22:38:41

常用技能:http://www.cnblogs.com/dunitian/p/4822808.html#skill

逆天博客:http://dnt.dkil.net

逆天通用水印支持Winform,WPF,Web,WP,Win10。支持位置选择(9个位置 ==》[X]):http://www.cnblogs.com/dunitian/p/4939369.html

本次添加了一些新东西,比如剪贴板之类的水印操作。完善了部分功能(比如文件过滤,非Bitmap图片的处理,以及一些其他玩意等待你的发现)

先贴下新增的效果:

单个图片水印

逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能

多文件直接水印

逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能

 

网页图片批量转

逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能

word文档图片批量转

逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能

剪贴板图片水印

逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能

自动化配置

逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能

上篇重复的技术点我就不继续说了,这次主要贴一下剪贴板系列的code

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
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
 
namespace WaterMarkAPP.Common
{
    public class ClipboardHelper
    {
        /// <summary>
        /// 获取剪贴板里的图片
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<string> GetImagePathList()
        {
            var imgPathList = new List<string>();
            var data = Clipboard.GetDataObject();
            var formats = data.GetFormats();
            //二进制存储 (存储在剪贴板的截图|画画图内的图片)
            if (data.GetDataPresent(DataFormats.Dib, true))
            {
                var imgSorce = Clipboard.GetImage();
                Bitmap bmp = new Bitmap(imgSorce.PixelWidth, imgSorce.PixelHeight, PixelFormat.Format32bppPArgb);
                BitmapData bmpdata = bmp.LockBits(new Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppPArgb);
                imgSorce.CopyPixels(Int32Rect.Empty, bmpdata.Scan0, bmpdata.Height * bmpdata.Stride, bmpdata.Stride);
                bmp.UnlockBits(bmpdata);
                CreateDirectory();
                string filePath = string.Format(@"Images\{0}.png", Guid.NewGuid());
                bmp.Save(filePath, ImageFormat.Png);
                imgPathList.Add(filePath);
            }
            //图片文件
            if (data.GetDataPresent(DataFormats.FileDrop, true))
            {
                string[] objs = (string[])data.GetData(DataFormats.FileDrop, true);
                if (objs != null)
                {
                    for (int i = 0; i < objs.Length; i++)
                    {
                        imgPathList.Add(objs[i]);
                    }
                }
            }
            //剪贴板内单文件
            if (data.GetDataPresent(DataFormats.Bitmap, true))
            {
                string filePath = SaveImg(data.GetData(DataFormats.Bitmap, trueas Bitmap);
                if (filePath != null) { imgPathList.Add(filePath); }
            }
            //HTML页面里面的图片(网页 + word)
            if (data.GetDataPresent(DataFormats.Html, true))
            {
                var obj = data.GetData(DataFormats.Html, true);
                if (obj != null)
                {
                    string dataStr = obj.ToString();
                    imgPathList.AddRange(DownloadImg(dataStr));
                }
 
            }
            return imgPathList;
        }
 
        /// <summary>
        /// 保存图片,返回图片地址
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        private static string SaveImg(Bitmap bitmap)
        {
            if (bitmap == null) { return null; }
            CreateDirectory();
            string filePath = string.Format(@"Images\{0}.png", Guid.NewGuid());
            try { bitmap.Save(filePath, ImageFormat.Png); return filePath; }
            catch (Exception ex) { DNTLog(ex); return null; }
        }
 
        /// <summary>
        /// 批量下载图片
        /// </summary>
        /// <param name="dataStr">页面字符串</param>
        /// <param name="i">成功条数</param>
        /// <returns></returns>
        private static IEnumerable<string> DownloadImg(string dataStr)
        {
            var imgPathList = new List<string>();
            var collection = Regex.Matches(dataStr, @"<img([^>]*)\s*src=('|\"")([^'\""]+)('|\"")", RegexOptions.ECMAScript);
            WebClient webClient = new WebClient();
            foreach (Match item in collection)
            {
                string imgPath = item.Groups[3].Value;
                try
                {
                    CreateDirectory();
                    string filePath = string.Format(@"Images\{0}", Path.GetFileName(imgPath));
                    webClient.DownloadFile(item.Groups[3].Value, filePath);//剪贴板的图片没有相对路径
                    imgPathList.Add(string.Format(@"{0}\{1}", Directory.GetCurrentDirectory(), filePath));
                }
                catch (Exception ex) { DNTLog(ex); }
            }
            return imgPathList;
        }
 
        private static void DNTLog(Exception ex)
        {
            File.WriteAllText("log.dnt", ex.ToString(), Encoding.UTF8);
        }
 
        /// <summary>
        /// 创建文件夹
        /// </summary>
        private static void CreateDirectory()
        {
            if (!Directory.Exists("Images"))
            {
                Directory.CreateDirectory("Images");
            }
        }
    }
}

水印帮助类注意点

逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能

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
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Text;
using WaterMarkAPP.Enums;
using WaterMarkAPP.Model;
 
namespace WaterMarkAPP.Common
{
 
    /// <summary>
    /// 水印帮助类
    /// </summary>
    public class WaterMarkHelper
    {
        public static bool TryFromFile(string imgPath, ref Image img)
        {
            try
            {
                img = Image.FromFile(imgPath);
                return true;
            }
            catch
            {
                return false;
            }
        }
 
        #region 设置水印
        /// <summary>
        /// 设置水印
        /// </summary>
        /// <param name="imgPath"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public static Image SetWaterMark(string imgPath, WaterMark model)
        {
            Image imgSource = null;//背景图
            Image markImg = null;//水印图片
            if (!TryFromFile(imgPath, ref imgSource))
            {
                return null;
            }
 
            //水印检验(文字,图片[路径下是否存在图片])
            #region 水印校验+水印处理
            if (model == null) { return null; }
            if (!System.IO.File.Exists(imgPath)) { return null; }//看看原图是否存在
            //根据水印类型校验+水印处理
            switch (model.WaterMarkType)
            {
                case WaterMarkTypeEnum.Text:
                    if (string.IsNullOrEmpty(model.Text))
                    {
                        return null;
                    }
                    else
                    {
                        markImg = TextToImager(model);//水印处理-如果是文字就转换成图片
                    }
                    break;
                case WaterMarkTypeEnum.Image:
                    if (!System.IO.File.Exists(model.ImgPath))
                    {
                        return null;
                    }
                    else
                    {
                        if (!TryFromFile(model.ImgPath, ref markImg))//获得水印图像
                        {
                            return imgSource;
                        }
                    }
                    break;
                case WaterMarkTypeEnum.NoneMark:
                    return imgSource;
            }
            #endregion
 
            #region 创建颜色矩阵
            //创建颜色矩阵
            float[][] ptsArray ={
                                 new float[] {1, 0, 0, 0, 0},
                                 new float[] {0, 1, 0, 0, 0},
                                 new float[] {0, 0, 1, 0, 0},
                                 new float[] {0, 0, 0, model.Transparency, 0}, //注意:0.0f为完全透明,1.0f为完全不透明
                                 new float[] {0, 0, 0, 0, 1}};
            ColorMatrix colorMatrix = new ColorMatrix(ptsArray);
            //新建一个Image属性
            ImageAttributes imageAttributes = new ImageAttributes();
            //将颜色矩阵添加到属性
            imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Default);
            #endregion
 
            //原图格式检验+水印
            #region 原图格式检验+水印
            //判断是否是索引图像格式
            if (imgSource.PixelFormat == PixelFormat.Format1bppIndexed || imgSource.PixelFormat == PixelFormat.Format4bppIndexed || imgSource.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                #region 索引图片,转成位图再加图片
                //转成位图,这步很重要
                Bitmap bitmap = new Bitmap(imgSource.Width, imgSource.Height);
                Graphics graphic = Graphics.FromImage(bitmap);
 
                #region 缩放处理
                //如果原图小于水印图片 等比缩放水印图
                if (markImg.Width >= imgSource.Width || markImg.Height >= imgSource.Height)
                {
                    markImg = ImageShrink(imgSource, markImg);
                }
                #endregion
 
                #region 水印位置
                //水印位置
                int x;
                int y;
                WaterMarkLocations(model, imgSource, markImg, out x, out y);
                #endregion
 
                //将原图画在位图上
                graphic.DrawImage(imgSource, new Point(0, 0));
 
                //将水印加在位图上
                graphic.DrawImage(markImg, new Rectangle(x, y, markImg.Width, markImg.Height), 0, 0, markImg.Width, markImg.Height, GraphicsUnit.Pixel, imageAttributes);
 
                graphic.Dispose();
                return bitmap;
                #endregion
            }
            else
            {
                #region 非索引图片,直接在上面加上水印
                Graphics graphic = Graphics.FromImage(imgSource);
 
                #region 缩放处理
                //如果原图小于水印图片 等比缩放水印图
                if (markImg.Width >= imgSource.Width || markImg.Height >= imgSource.Height)
                {
                    markImg = ImageShrink(imgSource, markImg);
                }
                #endregion
 
                #region 水印位置
                //水印位置
                int x;
                int y;
                WaterMarkLocations(model, imgSource, markImg, out x, out y);
                #endregion
 
                //将水印加在原图上
                graphic.DrawImage(markImg, new Rectangle(x, y, markImg.Width, markImg.Height), 0, 0, markImg.Width, markImg.Height, GraphicsUnit.Pixel, imageAttributes);
 
                graphic.Dispose();
                return imgSource;
                #endregion
            }
            #endregion
        }
        #endregion
 
        #region 水印处理-文字转图片
        /// <summary>
        /// 水印处理-文字转图片
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private static Image TextToImager(WaterMark model)
        {
            Font f = new Font(model.FontFamily, model.FontSize, model.FontStyle);
            Bitmap fbitmap = new Bitmap(Encoding.GetEncoding("GBK").GetByteCount(model.Text) / 2 * f.Height, f.Height);
            Graphics gh = Graphics.FromImage(fbitmap);//创建一个画板;
            gh.SmoothingMode = SmoothingMode.AntiAlias;
            gh.DrawString(model.Text, f, model.BrushesColor, 0, 0);//画字符串
            return fbitmap as Image;
        }
        #endregion
 
        #region 水印位置
        /// <summary>
        /// 水印位置
        /// </summary>
        /// <param name="model"></param>
        /// <param name="imgSource"></param>
        /// <param name="markImg"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private static void WaterMarkLocations(WaterMark model, Image imgSource, Image markImg, out int x, out int y)
        {
            x = 0;
            y = 0;
            switch (model.WaterMarkLocation)
            {
                case WaterMarkLocationEnum.TopLeft:
                    x = 0;
                    y = 0;
                    break;
                case WaterMarkLocationEnum.TopCenter:
                    x = imgSource.Width / 2 - markImg.Width / 2;
                    y = 0;
                    break;
                case WaterMarkLocationEnum.TopRight:
                    x = imgSource.Width - markImg.Width;
                    y = 0;
                    break;
                case WaterMarkLocationEnum.CenterLeft:
                    x = 0;
                    y = imgSource.Height / 2 - markImg.Height / 2;
                    break;
                case WaterMarkLocationEnum.CenterCenter:
                    x = imgSource.Width / 2 - markImg.Width / 2;
                    y = imgSource.Height / 2 - markImg.Height / 2;
                    break;
                case WaterMarkLocationEnum.CenterRight:
                    x = imgSource.Width - markImg.Width;
                    y = imgSource.Height / 2 - markImg.Height / 2;
                    break;
                case WaterMarkLocationEnum.BottomLeft:
                    x = 0;
                    y = imgSource.Height - markImg.Height;
                    break;
                case WaterMarkLocationEnum.BottomCenter:
                    x = imgSource.Width / 2 - markImg.Width / 2;
                    y = imgSource.Height - markImg.Height;
                    break;
                case WaterMarkLocationEnum.BottomRight:
                    x = imgSource.Width - markImg.Width;
                    y = imgSource.Height - markImg.Height;
                    break;
            }
        }
        #endregion
 
        #region 缩放水印
        /// <summary>
        /// 等比缩放水印图(缩小到原图的1/3)
        /// </summary>
        /// <param name="imgSource"></param>
        /// <param name="successImage"></param>
        /// <returns></returns>
        private static Image ImageShrink(Image imgSource, Image markImg)
        {
            int w = 0;
            int h = 0;
 
            Image.GetThumbnailImageAbort callb = null;
 
            //对水印图片生成缩略图,缩小到原图的1/3(以短的一边为准)                    
            if (imgSource.Width < imgSource.Height)
            {
                w = imgSource.Width / 3;
                h = markImg.Height * w / markImg.Width;
            }
            else
            {
                h = imgSource.Height / 3;
                w = markImg.Width * h / markImg.Height;
            }
            markImg = markImg.GetThumbnailImage(w, h, callb, new System.IntPtr());
            return markImg;
        }
        #endregion
    }
}

 

源码参考:https://github.com/dunitian/DNTLive/tree/master/Software/WaterMarkAPP


本文转自毒逆天博客园博客,原文链接:http://www.cnblogs.com/dunitian/p/5377097.html,如需转载请自行联系原作者