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