逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能
常用技能:http://www.cnblogs.com/dunitian/p/4822808.html#skill
逆天博客:http://dnt.dkil.net
PSD源码:https://pan.baidu.com/s/1bo34763
通用水印V1.2 下载:https://pan.baidu.com/s/1NVelF7RvBJ_cUE8_eZKlQg
逆天通用水印支持Winform,WPF,Web,WP,Win10。支持位置选择(9个位置 ==》[X]):http://www.cnblogs.com/dunitian/p/4939369.html
本次添加了一些新东西,比如剪贴板之类的水印操作。完善了部分功能(比如文件过滤,非Bitmap图片的处理,以及一些其他玩意等待你的发现)
先贴下新增的效果:
单个图片水印
多文件直接水印
网页图片批量转
word文档图片批量转
剪贴板图片水印
自动化配置
上篇重复的技术点我就不继续说了,这次主要贴一下剪贴板系列的code
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, true) as 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"); } } } }
水印帮助类注意点
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