图片加水印

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Drawing.Drawing2D;

namespace OG
{
    public enum MarkType
    {
        Text,Image
    }

    /**//// <summary>
    /// 给图片添加水印得类得描述
    /// </summary>
    ///

    public class WaterMark
    {
        //---------------------成员变量---------------------#region ---------------------成员变量---------------------       
        private string _text="";
        private string _imgPath="";
        private int _markX=0;
        private int _markY=0;
        private int _markX1 = 0;
        private int _markY1 = 0;
        private float _transparency=1;
        private string _fontFamily="宋体";
        private Color _textColor=Color.Black;
        private bool _textbold=false;
        //int[] sizes=new int[]{48,32,16,8,6,4};
        int[] sizes = new int[] { 1000,950,900,850,800,750,700,650,600,550,500,450,400,350,300, 250, 200, 150,100,50,40,30,20,10,9,8,7,6,5,4,3,2,1 };
        private Image _image=null;
        private Image _markedIamge=null;
        private MarkType _markType=MarkType.Text;

        //---------------------构造函数---------------------#region ---------------------构造函数---------------------
        /**//// <summary>
        /// 实例化一个水印类
        /// </summary>
        ///

        public WaterMark()
        {
           
        }

        /**//// <summary>
        /// 初始化一个只添加文字水印得实例
        /// </summary>
        /// <param name="text">水印文字</param>
        /// <param name="fontFamily">文字字体</param>
        /// <param name="bold">是否粗体</param>
        /// <param name="color">字体颜色</param>
        /// <param name="markX">标记位置横坐标</param>
        /// <param name="markY">标记位置纵坐标</param>
        public WaterMark(string text, string fontFamily, bool bold, Color color, int markX, int markY, int markX1, int markY1, Image img)
        {   
            this._markType=MarkType.Text;
            this._text=text;
            this._fontFamily=fontFamily;
            this._textbold=bold;
            this._textColor=color;
            this._markX=markX;
            this._markY = markY;
            this._markX1 = markX1;
            this._markY1 = markY1;         
            this.SourceImage = img;
            this.Mark();
        }

         /**//// <summary>
        /// 实例化一个只添加图片水印得实例
        /// </summary>
        /// <param name="imagePath">水印图片路径</param>
        /// <param name="tranparence">透明度</param>
        /// <param name="markX">标记位置横坐标</param>
        /// <param name="markY">标记位置纵坐标</param>
        public WaterMark(string imagePath,float tranparence,int markX,int markY)
        {
            this._markType=MarkType.Image;       
            this._imgPath=imagePath;
            this._markX=markX;
            this._markY=MarkY;
            this._transparency=tranparence;
            this.Mark();
        }

        //---------------------方法事件---------------------#region ---------------------方法事件---------------------
        public Image Mark(Image img, MarkType markType, string text, Image waterImg, int markx, int marky, int markx1, int marky1,
            bool bold,Color textColor,float transparence,FontFamily fontFamily)
        {
            //首先先判断该图片是否是 gif动画,如果为gif动画不对图片进行改动
            int w = 0;
            SizeF size = new SizeF();
            foreach(Guid guid in img.FrameDimensionsList)
            {
                FrameDimension dimension= new FrameDimension(guid);
                if(img.GetFrameCount(dimension)>1)
                {
                    return img;
                }
            }
            try
            {
                //添加文字水印
                if(markType==MarkType.Text)
                {
                    //根据源图片生成新的Bitmap对象作为作图区,为了给gif图片添加水印,才有此周折
                    Bitmap newBitmap=new Bitmap(img.Width,img.Height,PixelFormat.Format24bppRgb);
                    //设置新建位图得分辨率
                    newBitmap.SetResolution(img.HorizontalResolution,img.VerticalResolution);
                    //创建Graphics对象,以对该位图进行操作
                    Graphics g = Graphics.FromImage(newBitmap);
                    //消除锯齿
                    g.SmoothingMode=SmoothingMode.AntiAlias;
                    //将原图拷贝到作图区
                    g.DrawImage(img,new Rectangle(0,0,img.Width,img.Height),0,0,img.Width,img.Height,GraphicsUnit.Pixel);
                    //声明字体对象
                    Font cFont = null;
                    //用来测试水印文本长度得尺子

                    //探测出一个适合图片大小得字体大小,以适应水印文字大小得自适应
                    for(int i=0;i<33;i++)
                    {
                        //创建一个字体对象
                        cFont= new Font(fontFamily,sizes[i]);
                        //是否加粗
                        if(!bold)
                        {
                            cFont= new Font(fontFamily,sizes[i],FontStyle.Regular);
                        }
                        else
                        {
                            cFont=new Font(fontFamily,sizes[i],FontStyle.Bold);
                        }
                        //测量文本大小
                        size=g.MeasureString(this.Text,cFont);
                        //匹配第一个符合要求得字体大小
                        if((ushort)size.Width<(ushort)img.Width)
                        {

                            break;
                        }
                    }

                    textColor = Color.FromArgb(100, textColor);
                    //创建刷子对象,准备给图片写上文字
                    Brush brush= new SolidBrush(textColor);
                    //在指定得位置写上文字
                    w = img.Width - (ushort)size.Width;
                    markx = Convert.ToInt16(w / 2);
                    markx1 = markx;
                    g.DrawString(text,cFont,brush,markx,marky);

                    g.DrawString(text, cFont, brush, markx1, marky1);

                    //g.DrawString(text, cFont, brush, markx, Convert.ToInt16(Convert.ToDouble(img.Width)*0.8));
                    //释放Graphics对象
                    g.Dispose();  
                    //将生成得图片读入MemoryStream
                    System.IO.MemoryStream ms = new System.IO.MemoryStream();
                    newBitmap.Save(ms,ImageFormat.Jpeg);
                    //重新生成Image对象
                    img=System.Drawing.Image.FromStream(ms);   
                    //返回新的Image对象
                    return img;

                }
                //添加图像水印
                else if(markType==MarkType.Image)
                {
                    //获得水印图像
                    Image markImg = waterImg;
                    //创建颜色矩阵
                    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, transparence, 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);
                    //生成位图作图区
                    Bitmap newBitmap=new Bitmap(img.Width,img.Height,PixelFormat.Format24bppRgb);
                    //设置分辨率
                    newBitmap.SetResolution(img.HorizontalResolution,img.VerticalResolution);
                    //创建Graphics
                    Graphics g = Graphics.FromImage(newBitmap);
                    //消除锯齿
                    g.SmoothingMode=SmoothingMode.AntiAlias;
                    //拷贝原图到作图区
                    g.DrawImage(img,new Rectangle(0,0,img.Width,img.Height),0,0,img.Width,img.Height,GraphicsUnit.Pixel);
                    //如果原图过小
                    if(markImg.Width>img.Width||markImg.Height>img.Height)
                    {
                        System.Drawing.Image.GetThumbnailImageAbort callb=null;
                        //对水印图片生成缩略图,缩小到原图得1/4
                        System.Drawing.Image new_img=markImg.GetThumbnailImage(img.Width/4,markImg.Height*img.Width/markImg.Width,callb,new System.IntPtr());
                        //添加水印
                        g.DrawImage(new_img,new Rectangle(markx,marky,new_img.Width,new_img.Height),0,0,new_img.Width,new_img.Height,GraphicsUnit.Pixel,imageAttributes);
                        //释放缩略图
                        new_img.Dispose();
                        //释放Graphics
                        g.Dispose();
                        //将生成得图片读入MemoryStream
                        System.IO.MemoryStream ms = new System.IO.MemoryStream();
                        newBitmap.Save(ms,ImageFormat.Jpeg);
          //返回新的Image对象
                        img=Image.FromStream(ms);
                        return img;
                    }
                        //原图足够大
                    else
                    {
                        //添加水印
                        g.DrawImage(markImg,new Rectangle(markx,marky,markImg.Width,markImg.Height),0,0,markImg.Width,markImg.Height,GraphicsUnit.Pixel,imageAttributes);
                        //释放Graphics
                        g.Dispose();
                        //将生成得图片读入MemoryStream
                        System.IO.MemoryStream ms = new System.IO.MemoryStream();
                        newBitmap.Save(ms,ImageFormat.Jpeg);
                        //返回新的Image对象
                        img=Image.FromStream(ms);
                        return img;
                    }                   
                }
                return img;
            }
            catch
            {
                return img;  
            }           

        }
        /**//// <summary>
        /// 添加水印,此方法适用于gif格式得图片
        /// </summary>
        /// <param name="image">需要添加水印得图片</param>
        /// <returns>添加水印之后得图片</returns>
        private void Mark()
        {
            MarkedImage = Mark(this.SourceImage, this.WaterMarkType, this._text, this.WaterImage, this._markX, this._markY, this._markX1, this._markY1, this._textbold, this._textColor, this._transparency, this.TextFontFamily);
        }
        #region 公用属性
        /**/
        /// <summary>
        /// 水印类型
        /// </summary>
        public MarkType WaterMarkType
        {
            get
            {
                return _markType;
            }
            set
            {
                _markType = value;
            }
        }
        /**/
        /// <summary>
        /// 文字水印得内容
        /// </summary>
        public string Text
        {
            get { return _text; }
            set { _text = value; }
        }
        /**/
        /// <summary>
        /// 水印图片得路径
        /// </summary>
        public string WaterImagePath
        {
            get
            {
                return _imgPath;
            }
            set
            {
                this._imgPath = value;
            }
        }
        /**/
        /// <summary>
        /// 水印图片
        /// </summary>
        public Image WaterImage
        {
            get
            {
                try
                {
                    return Image.FromFile(this.WaterImagePath);
                }
                catch
                {
                    return null;
                }
            }
        }
        /**/
        /// <summary>
        /// 添加水印位置得横坐标
        /// </summary>
        public int MarkX
        {
            get { return _markX; }
            set { _markX = value; }
        }
        /**/
        /// <summary>
        /// 添加水印位置得纵坐标
        /// </summary>
        public int MarkY
        {
            get { return _markY; }
            set { _markY = value; }
        }
        /**/
        /// <summary>
        /// 水印得透明度
        /// </summary>
        public float Transparency
        {
            get
            {
                if (_transparency > 1.0f)
                {
                    _transparency = 1.0f;
                }
                return _transparency;
            }
            set { _transparency = value; }
        }
        /**/
        /// <summary>
        /// 水印文字得颜色
        /// </summary>
        public Color TextColor
        {
            get { return _textColor; }
            set { _textColor = value; }
        }
        /**/
        /// <summary>
        /// 水印文字得字体
        /// </summary>
        public string TextFontFamilyStr
        {
            get { return _fontFamily; }
            set { _fontFamily = value; }
        }
        public FontFamily TextFontFamily
        {
            get { return new FontFamily(this.TextFontFamilyStr); }
        }
        /**/
        /// <summary>
        /// 水印文字是否加粗
        /// </summary>
        public bool Bold
        {
            get { return _textbold; }
            set { _textbold = value; }
        }
        /**/
        /// <summary>
        /// 原图
        /// </summary>
        public Image SourceImage
        {
            get
            {
                return _image;
            }
            set
            {
                _image = value;
            }
        }
        /**/
        /// <summary>
        /// 加过水印之后得图
        /// </summary>
        public Image MarkedImage
        {
            get
            {
                return this._markedIamge;
            }
            set
            {
                this._markedIamge = value;
            }
        }


        #endregion
    }
}
调用方法:
                    System.Drawing.Image myImage = null; 
                    myImage=System.Drawing.Image.FromFile("图片路径")://得到某张图片的myimage对像

                    OG.WaterMark water = new OG.WaterMark("TodayComic 今日漫画", "宋体", true, Color.White, 0, Convert.ToInt16(h / 4), 0, Convert.ToInt16(h / 2), myImage);
                    myImage = water.MarkedImage;
                    myImage.Save(path);
                    return picname;

posted on   魏绰  阅读(237)  评论(1编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示