专栏首页逸鹏说道逆天通用水印支持Winform,WPF,Web,WP,Win10。支持位置选择(9个位置 ==》[X])

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

好几天没上QQ了,今天上了个QQ,,额....额...貌似消息还挺多,没及时回复的还请见谅~~刚好昨天无聊把水印这快封装出来了,支持图片水印,文字水印,索引图水印和非索引图水印,支持位置选择(9个位置 ==》[X])。好吧不高兴屁话了,软件是WPF的(只满足我的需求,如果有需要可以出第个二版本),水印核心代码封装了个Helper类(通用:支持Winform,WPF,Web,WP,Win10)
软件共享一下==>http://pan.baidu.com/s/1qWDwv4C 
源码 http://pan.baidu.com/s/1gd1300z

水印类

/// <summary>
/// 水印类(重要参数:原图类型,水印类型,水印位置,图片水印路径,文字水印内容)
/// </summary>
public class WaterMark
{
    #region 基础属性设置
    private string _photoType;
    /// <summary>
    /// 原图类型
    /// </summary>
    public string PhotoType
    {
        get { return _photoType; }
        set { _photoType = value; }
    }

    private WaterMarkTypeEnum _waterMarkType = WaterMarkTypeEnum.NoneMark;
    /// <summary>
    /// 水印类型
    /// </summary>
    public WaterMarkTypeEnum WaterMarkType
    {
        get { return _waterMarkType; }
        set { _waterMarkType = value; }
    }
    #endregion

    #region 水印效果设置
    private WaterMarkLocationEnum _waterMarkLocation = WaterMarkLocationEnum.BottomRight;
    /// <summary>
    /// 水印位置
    /// </summary>
    public WaterMarkLocationEnum WaterMarkLocation
    {
        get { return _waterMarkLocation; }
        set { _waterMarkLocation = value; }
    }

    private float _transparency = 0.7f;
    /// <summary>
    /// 水印透明度
    /// </summary>
    public float Transparency
    {
        get { return _transparency; }
        set { _transparency = value; }
    }
    #endregion

    #region 图片水印设置
    private string _imgPath;
    /// <summary>
    /// 图片水印路径
    /// </summary>
    public string ImgPath
    {
        get { return _imgPath; }
        set { _imgPath = value; }
    }
    #endregion

    #region 文字水印设置
    private string _text = "dunitian";
    /// <summary>
    /// 文字水印内容
    /// </summary>
    public string Text
    {
        get { return _text; }
        set { _text = value; }
    }

    private string _fontFamily = "微软雅黑";
    /// <summary>
    /// 文字字体
    /// </summary>
    public string FontFamily
    {
        get { return _fontFamily; }
        set { _fontFamily = value; }
    }

    private Brush _brushesColor = Brushes.Black;
    /// <summary>
    /// 文字颜色
    /// </summary>
    public Brush BrushesColor
    {
        get { return _brushesColor; }
        set { _brushesColor = value; }
    }

    private  FontStyle _fontStyle = FontStyle.Regular;
    /// <summary>
    /// 字体样式
    /// </summary>
    public FontStyle FontStyle
    {
        get { return _fontStyle; }
        set { _fontStyle = value; }
    }

    private float _fontSize = 14f;
    /// <summary>
    /// 字体大小
    /// </summary>
    public float FontSize
    {
        get { return _fontSize; }
        set { _fontSize = value; }
    }
    #endregion
}

 水印位置枚举

/// <summary>
/// 水印位子
/// </summary>
public enum WaterMarkLocationEnum
{
    /// <summary>
    /// 顶部居左
    /// </summary>
    TopLeft = 1,
    /// <summary>
    /// 顶部居中
    /// </summary>
    TopCenter = 2,
    /// <summary>
    /// 顶部居右
    /// </summary>
    TopRight = 3,
    /// <summary>
    /// 中部居左
    /// </summary>
    CenterLeft = 4,
    /// <summary>
    /// 中部居中
    /// </summary>
    CenterCenter = 5,
    /// <summary>
    /// 中部居右
    /// </summary>
    CenterRight = 6,
    /// <summary>
    /// 底部居左
    /// </summary>
    BottomLeft = 7,
    /// <summary>
    /// 底部居左
    /// </summary>
    BottomCenter = 8,
    /// <summary>
    /// 底部居左
    /// </summary>
    BottomRight = 9,
}

 水印类型枚举

/// <summary>
    /// 水印类型
    /// </summary>
    public enum WaterMarkTypeEnum
    {
        /// <summary>
        /// 文字
        /// </summary>
        Text = 1,
        /// <summary>
        /// 图片
        /// </summary>
        Image = 2,
        /// <summary>
        /// 无水印
        /// </summary>
        NoneMark = 3
    }

 水印帮助类(自己封装的,有bug可以像我反馈)

/// <summary>
/// 水印帮助类
/// </summary>
public class WaterMarkHelper
{
    #region 设置水印
    /// <summary>
    /// 设置水印
    /// </summary>
    /// <param name="imgPath"></param>
    /// <param name="model"></param>
    /// <returns></returns>
    public static Image SetWaterMark(string imgPath, WaterMark model)
    {
        //获取背景图
        Image imgSource = Image.FromFile(imgPath);
        //获取水印图片
        Image markImg = null;

        //水印检验(文字,图片[路径下是否存在图片])
        #region 水印校验+水印处理
        if (model == null)
        {
            return null;
        }
        //看看原图是否存在
        if (!System.IO.File.Exists(imgPath))
        {
            return null;
        }
        //根据水印类型校验+水印处理
        switch (model.WaterMarkType)
        {
            case WaterMarkAPP.Enums.WaterMarkTypeEnum.Text:
                if (string.IsNullOrEmpty(model.Text))
                {
                    return null;
                }
                else
                {
                    markImg = TextToImager(model);//水印处理-如果是文字就转换成图片
                }
                break;
            case WaterMarkAPP.Enums.WaterMarkTypeEnum.Image:
                if (!System.IO.File.Exists(model.ImgPath))
                {
                    return null;
                }
                else
                {
                    //获得水印图像          
                    markImg = Image.FromFile(model.ImgPath);
                }
                break;
            case WaterMarkAPP.Enums.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
}

  简单调用:

文字水印调用:

/// <summary>
/// 文字水印调用
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Click(object sender, RoutedEventArgs e)
{
    //给水印对象赋对应的值
    WaterMark waterMark = new WaterMark();
    waterMark.WaterMarkType = Enums.WaterMarkTypeEnum.Text;
    waterMark.Transparency = 0.7f;
    waterMark.Text = "dunitian.cnblogs.com";
    waterMark.FontStyle = System.Drawing.FontStyle.Bold;
    waterMark.FontFamily = "Consolas";
    waterMark.FontSize = 20f;
    waterMark.BrushesColor = System.Drawing.Brushes.YellowGreen;
    waterMark.WaterMarkLocation = Enums.WaterMarkLocationEnum.CenterCenter;

    //调用
    Image successImage = WaterMarkHelper.SetWaterMark("text.png", waterMark);
    //保存
    successImage.Save("text1.png", System.Drawing.Imaging.ImageFormat.Png);

    MessageBox.Show("请查看软件根目录", "成功");
}

  图片水印调用:

/// <summary>
        /// 图片水印调用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            //给水印对象赋对应的值
            WaterMark waterMark = new WaterMark();
            waterMark.WaterMarkType = Enums.WaterMarkTypeEnum.Image;
            waterMark.ImgPath = "水印.png";
            waterMark.WaterMarkLocation = Enums.WaterMarkLocationEnum.CenterCenter;
            waterMark.Transparency = 0.7f;

            //调用
            Image successImage = WaterMarkHelper.SetWaterMark("text.png", waterMark);
            //保存
            successImage.Save("text2.png", System.Drawing.Imaging.ImageFormat.Png);

            MessageBox.Show("请查看软件根目录","成功");
        }

  软件源码:(helper类不是最新,用上文的helper类)

 (调用部分我做了一个通用apidemo)

效果:

 源码下载:http://pan.baidu.com/s/1gd1300z

本文分享自微信公众号 - 我为Net狂(dotNetCrazy),作者:dunitian

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-11-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 水印新思路之~坑人于无形

    有空可以研究一下。很多注重图片版权的公司完全可以设置这种无形水印,发现被人盗用,直接可以拿图告人,拿图找泄密者~ 本文通过一个的实验,简要介绍频域手段添加数字盲...

    逸鹏
  • 水印第三版 ~ 变态水印(这次用Magick.NET来实现,附需求分析和源码)

    技能 汇总:http://www.cnblogs.com/dunitian/p/4822808.html#skill 以前的水印,只是简单走起,用的是原生态的方...

    逸鹏
  • 本地密码检索工具 – LaZagne Project

    简介 LaZagne project 是一款用于检索大量存储在本地计算机上密码的开源应用程序。每款软件他们保存密码的方法或许不尽相同(明文,API,算法,数据库...

    逸鹏
  • 5个精选实用的微信小程序,个个都是值得收藏!

    现在的年轻人越来越喜欢用微信进行联系他人,每次打开手机,首先点进去的就是微信,看看消息,打打视频什么的,其实在微信中除了可以操作这些之外,还隐藏了其他的功能,如...

    一点都不胖
  • 支持 Dubbo 接口文档生成的工具

    smart-doc是一款同时支持JAVA REST API和Apache Dubbo RPC接口文档生成的工具,smart-doc在业内率先提出基于JAVA泛型...

    JAVA葵花宝典
  • 网络犯罪自助化:CaaS产业链

    提起“黑客”、“数字武器”、“网络攻击”等等字眼,大众的第一印象往往是“神秘”、“无所不能”的技术极客,然而这个情况在最近几年有了很大的变化。

    用户6477171
  • 微信是什么? 你如何用微信决定了它到底是什么

      微信是什么?我们每天用微信和朋友语音聊天、刷朋友圈、摇妹子、玩飞机大战...却没有真正去想过这个问题。那微信之父张小龙是如何define微信的呢?他并没有正...

    ytkah
  • Flutter代码模板,解放双手,提高开发效率必备

    版权声明:本文为博主原创文章,未经博主允许不得转载。https://www.jianshu.com/p/4184745d6983 转载请标明出处:https:...

    AWeiLoveAndroid
  • 漫画:什么是旅行商问题?

    有一个快递员,要分别给三家顾客送快递,他自己到达每个顾客家的路程各不相同,每个顾客之间的路程也各不相同。

    小灰
  • 18-STM32+ESP8266+AIR202基本控制篇-完成功能4-微信小程序扫描GPRS二维码绑定设备,并通过MQTT和air202实现远程通信控制(兼容SIM800)

    说明 前面章节已经搭建好了服务器可以实现 微信小程序扫码绑定Air202,并通过MQTT和air202实现远程通信控制(兼容SIM800) 单片机程序修改(修...

    杨奉武

扫码关注云+社区

领取腾讯云代金券