常用技能: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

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

  1. 逆天通用水印支持Winform,WPF,Web,WP,Win10。支持位置选择(9个位置 ==》[X])...

    常用技能:http://www.cnblogs.com/dunitian/p/4822808.html#skill 逆天博客:http://dnt.dkil.net 逆天通用水印扩展篇~新增剪贴板系列 ...

  2. 【系】微信小程序云开发实战坚果商城-扩展篇

    第 5-1 课:扩展篇 目录 开篇 [系]微信小程序云开发实战坚果商城-开篇 基础篇 [系]微信小程序云开发实战坚果商城-弹性盒子 [系]微信小程序云开发实战坚果商城-ES6 简单入门 [系]微信小程 ...

  3. 从零开始学架构4 - 可扩展篇

    从零开始学架构4 - 可扩展篇 32 | 可扩展架构的基本思想和模式 今天我们进入架构可扩展模式的学习,这部分内容包括分层架构.SOA 架构.微服务和微内核等,先来聊聊架构的可扩展模式. 可扩展的基本 ...

  4. 23篇大数据系列(一)java基础知识全集(2万字干货,建议收藏)

    大数据系列爽文,从技术能力.业务基础.分析思维三大板块来呈现,你将收获: ❖ 提升自信心,自如应对面试,顺利拿到实习岗位或offer: ❖ 掌握大数据的基础知识,与其他同事沟通无障碍: ❖ 具备一定的 ...

  5. cicd 08--基于Jenkins的通用可扩展CICD架构

    cicd 08--基于Jenkins的通用可扩展CICD架构 1 介绍 2 架构 2.1 架构图 2.2 主要模块功能 3 案例 3.1 场景说明 3.2 Job-multi 的功能脚本 3.3 执行 ...

  6. 测试用例(五)(扩展篇)

    2018-08-22  10:04:09 故障模型---缺陷查找攻击的二十一招大法 3.输入特殊字符集 根据被测软件的具体情况输入非法字符. 多了解ASCII 字符集.程序设计语言和OS中的保留字符串 ...

  7. python解复杂方程_Python数据处理篇之Sympy系列(五)---解方程

    前言 sympy不仅在符号运算方面强大,在解方程方面也是很强大. 本章节学习对应官网的:Solvers 官方教程 (一)求解多元一次方程-solve() 1.说明: 解多元一次方程可以使用solve( ...

  8. Puppet扩展篇1-自定义fact结合ENC(hirea)的应用实践

    零基础学习Puppet自动化配置管理系列文档 在大量节点加入Puppet之后,你至少会面临两个比较大的问题: 1.由于节点数的增多,site.pp文件必然会编写更多的节点条目,以及节点包含的类.假设你 ...

  9. 【CORE JAVA】反射应用:通用方法-扩展数组长度

    为什么80%的码农都做不了架构师?>>>    /** * 通用数组扩展方法 * 可以使用Object类型的变量引用任何类型的对象 * 用Array.newInstance(comp ...

  10. WEB攻击手段及防御-扩展篇

    转载自 WEB攻击手段及防御-扩展篇 之前的文章介绍了常见的XSS攻击.SQL注入.CSRF攻击等攻击方式和防御手段,没有看的去翻看之前的文章,这些都是针对代码或系统本身发生的攻击,另外还有一些攻击方 ...

最新文章

  1. Boost源码剖析之:容器赋值-assign
  2. topcoder-SRM565-div2-第二题-500分--搜索/动态规划
  3. php post 过滤,ThinkPHP技巧-POST过滤
  4. android 字符串的拆分
  5. 前端学习(1607):跨域请求
  6. Sharepoin学习笔记—架构系列--08 Sharepoint的数据模型(DataModel)、数据管理(Data Management)与查询(Query System)
  7. Android之事件分发机制
  8. 谷歌大脑推出机器人强化学习平台,硬件代码全开源,花最少的钱,训超6的机器人...
  9. C++ queue用法
  10. Python 数据科学手册 5.6 线性回归
  11. C#多线程的用法2-线程的生命周期
  12. C1. Simple Polygon Embedding(计算几何)
  13. K3 CLOUD组织间结算取价指引
  14. 介绍一下大型企业数据防泄密产品选型的思路
  15. 我们为什么要结婚?(
  16. 微信PC端有了新功能,快来看看你知不知道
  17. 数据挖掘与分析——关联规则模型
  18. EOS学习系统---BPS工作流程
  19. Android设置壁纸的几种方案
  20. 移民去欧洲,选哪个国家好呢?

热门文章

  1. Atitit避免出现空指针异常解决方案
  2. paip.中文 分词 -- 同义词大全整理
  3. 【疑问】互联网公募基金的销售是繁荣,还是乱象?
  4. Vanguard集团在美上市ETF资产超8700亿美元
  5. Julia :PyPlot库安装中需注意的问题
  6. 机器学习笔记(一):机器的学习定义、导数和最小二乘 | 凌云时刻
  7. c语言怎样用vc绘图,大佬们,小菜鸟想问一问用vc编译器做简易画图软件
  8. 【图像去噪】基于matlab GUI DCT图像去噪【含Matlab源码 614期】
  9. 【语音去噪】基于matlab低通+自适应滤波去噪【含Matlab源码 352期】
  10. java mongodb 读取文件_Java操作Mongodb之文件读写