给图片添加水印的C#类库

相关文件下载:

1. 给图片添加水印的类库(dll)文件:ImageHandler.dll (18.00 kb)

2. 整个类库项目文件:ImageHandler.rar (45.03 kb) 

摘要:

本文提供了一个给图片添加水印的C#类库,首先介绍了它的使用方法,其次介绍了该类库的结构,最后公开了它的源代码以及整个项目文件。

简介:

上篇文章介绍了使用C#及GDI+技术给图片添加水印的原理和技术细节。本文使用其技术做底层实现,采用模板设计模式架构,提供了一个高复用性与易扩展的图片处理类库。

 给图片添加水印的C#类库 The C# Class Library for adding watermark to image

一、类库的使用:

将类库(ImageHandler.dll (18.00 kb))复制到你的工程Bin文件夹后,在你的代码中添加zizhujy.ImageHandler命名空间,然后打开你要添加水印的图片,实例化一个zizhujy.ImageHandler中的Watermarker类,添加你想要的水印,完毕。就是如此简单!它可以被引用到Windows Console Application、Windows Form Application、Web Application、Web Service Application 等等工程中,以下以ASP.NET MVC 3 Application为例,就文字水印与图片水印分别列出三个代码实例。

1. 添加文字水印:

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using zizhujy.ImageHandler;
 
namespace zizhujy.Controllers
{
    public class TestController : Controller
    {
        public void AddWatermark()
        {
            Image originImage = Image.FromFile(@"C:\source.jpg");
            TextWatermarker txtWatermarker = new TextWatermarker(originImage, "www.zizhujy.com");
            txtWatermarker.AddWatermark();
 
            // Response and show the watermarked image in the browser
            Response.ContentType = "image/jpeg";
            txtWatermarker.WatermarkedImage.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
 
            txtWatermarker.Dispose();
            originImage.Dispose();
        }
    }
}

效果:

给图片添加水印的C#类库 The C# Class Library for adding watermark to image

2. 添加图片水印:

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using zizhujy.ImageHandler;
 
namespace zizhujy.Controllers
{
    public class TestController : Controller
    {
        public void AddWatermark()
        {
            Image originImage = Image.FromFile(@"C:\source.jpg");
            Image watermark = Image.FromFile(@"C:\clock.png");
 
            ImageWatermarker imgWatermarker = new ImageWatermarker(originImage, watermark);
            imgWatermarker.AddWatermark();
 
            // Response and show the watermarked image in the browser
            Response.ContentType = "image/jpeg";
            imgWatermarker.WatermarkedImage.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
 
            imgWatermarker.Dispose();
            watermark.Dispose();
            originImage.Dispose();
        }
    }
}

效果:

给图片添加水印的C#类库 The C# Class Library for adding watermark to image

 

3. 同时添加图片水印和文字水印:

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using zizhujy.ImageHandler;
 
namespace zizhujy.Controllers
{
    public class TestController : Controller
    {
        public void AddWatermark()
        {
            // First, add the image watermark
            Image originImage = Image.FromFile(@"C:\source.jpg");
            Image watermark = Image.FromFile(@"C:\clock.png");
 
            ImageWatermarker imgWatermarker = new ImageWatermarker(originImage, watermark);
            // You can set the watermark size, if you not then the watermark will be its original size by default
            imgWatermarker.SetWatermarkHeight(80);
            imgWatermarker.AddWatermark();
 
            // Second, add the text watermark
            TextWatermarker txtWatermarker = new TextWatermarker(imgWatermarker.WatermarkedImage, "www.zizhujy.com");
            // You can set the position of the watermark
            txtWatermarker.Position = WatermarkPostion.TopLeft;
            txtWatermarker.AddWatermark();
 
            // Response and show the watermarked image in the browser
            Response.ContentType = "image/jpeg";
            // Note: save the secondly watermarked image 
            //  (txtWatermarker not imgWatermarker because the txtWatermarker comes after than imgWatermarker)
            txtWatermarker.WatermarkedImage.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
 
            imgWatermarker.Dispose();
            watermark.Dispose();
            originImage.Dispose();
        }
    }
}

效果:

给图片添加水印的C#类库 The C# Class Library for adding watermark to image

二、类库的结构(设计模式)

此类库采用了模板设计模式。因为对于给图片加水印,至少分为文本水印、图片水印两种。而不同的水印,将其添加到图片上的算法是一样的。即

  1. 获取源图片
  2. 获取水印
  3. 计算水印的位置Point (x,y)
  4. 计算水印的大小Size (width, height)
  5. 在源图片的Point位置处,以Size尺寸,将水印绘制出来,并返回新的图片

因此很自然想到使用模板设计模式,将以上算法封装在模板类Watermarker类中。对于图片水印与文本水印如何添加到源图片上,其方法是不一样的(详见上篇文章说明),故上述第5步,绘制水印的方法应该是抽象的,由具体的类来给予实现,即分别在ImageWatermarker和TextWatermarker中实现。

类图结构如下:

给图片添加水印的C#类图 The C# Class Diagram for adding watermark to image

很简单明了,后面三个Enum是用来表示水印在源图片上出现的位置的struct结构体。

以下分别看每个类的结构:

 给图片添加水印的C#类图 The C# Class Diagram for adding watermark to image 给图片添加水印的C#类图 The C# Class Diagram for adding watermark to imageimage
 给图片添加水印的C#类图 The C# Class Diagram for adding watermark to image 给图片添加水印的C#类图 The C# Class Diagram for adding watermark to image 给图片添加水印的C#类图 The C# Class Diagram for adding watermark to image

三、类库的源码

先看模板类Watermarker.cs的源码(三个Enum结构体的代码也在这个文件中):

using System;
using System.Drawing;
 
namespace zizhujy.ImageHandler
{
    /// 
    /// Watermarker Template class
    /// 
    public abstract class Watermarker : IDisposable
    {
        #region Properties
 
        private Image originImage;
        public Image OriginImage
        {
            get
            {
                return originImage;
            }
            set
            {
                originImage = value;
            }
        }
 
        private Image watermarkedImage;
        public Image WatermarkedImage
        {
            get
            {
                return watermarkedImage;
            }
            set
            {
                watermarkedImage = value;
            }
        }
 
        private SizeF watermarkSize;
        protected SizeF WatermarkSize
        {
            get
            {
                return watermarkSize;
            }
            set
            {
                watermarkSize = value;
            }
        }
 
        private float x;
        protected float X
        {
            get
            {
                return x;
            }
            set
            {
                x = value;
            }
        }
 
        private float y;
        protected float Y
        {
            get
            {
                return y;
            }
            set
            {
                y = value;
            }
        }
 
        private bool computeX = true;
        public bool ComputeX
        {
            get { return computeX; }
        }
 
        private bool computeY = true;
        public bool ComputeY
        {
            get { return computeY; }
        }
 
        private WatermarkHorizontalPostion hPos;
        public WatermarkHorizontalPostion HorizontalPosition
        {
            get
            {
                return hPos;
            }
            set
            {
                computeX = true;
                hPos = value;
            }
        }
 
        private WatermarkVerticalPostion vPos;
        public WatermarkVerticalPostion VerticalPosition
        {
            get
            {
                return vPos;
            }
            set
            {
                computeY = true;
                vPos = value;
            }
        }
 
        public WatermarkPostion Position
        {
            get
            {
                return GetPosition(this.HorizontalPosition , this.VerticalPosition) ;
            }
            set
            {
                this.HorizontalPosition = GetHorizentalPosition(value);
                this.VerticalPosition = GetVerticalPosition(value);
            }
        }
 
        private int hMarginPixel;
        public int HorizontalMarginPixel
        {
            get
            {
                return hMarginPixel;
            }
            set
            {
                hMarginPixel = value;
            }
        }
 
        private int vMarginPixel;
        public int VerticalMarginPixel
        {
            get
            {
                return vMarginPixel;
            }
            set
            {
                vMarginPixel = value;
            }
        }
 
        public double HorizontalMarginPercent
        {
            get
            {
                return this.HorizontalMarginPixel / this.OriginImage.Width;
            }
            set
            {
                double percent = value > 1 ? 1 : (value < 0 ? 0 : value);
                this.HorizontalMarginPixel = (int)(this.OriginImage.Width * percent);
            }
        }
 
        public double VerticalMarginPercent
        {
            get
            {
                return this.VerticalMarginPixel / this.OriginImage.Height;
            }
            set
            {
                double percent = value > 1 ? 1 : (value < 0 ? 0 : value);
                this.VerticalMarginPixel = (int)(this.originImage.Height * percent);
            }
        }
 
        private Color shadowColor;
        public Color ShadowColor
        {
            get
            {
                return shadowColor;
            }
            set
            {
                shadowColor = value;
            }
        }
 
        private Color foreColor;
        public Color ForeColor
        {
            get
            {
                return foreColor;
            }
            set
            {
                foreColor = value;
            }
        }
 
        public double ShadowOpacity
        {
            get
            {
                return shadowColor.A / 255;
            }
            set
            {
                double percent = value > 1 ? 1 : (value < 0 ? 0 : value);
                int alpha = (int)(255 * percent);
 
                shadowColor = Color.FromArgb(alpha, shadowColor);
            }
        }
 
        public virtual double ForegroundOpacity
        {
            get
            {
                return foreColor.A / 255;
            }
            set
            {
                double percent = value > 1 ? 1 : (value < 0 ? 0 : value);
                int alpha = (int)(255 * percent);
 
                foreColor = Color.FromArgb(alpha, foreColor);
            }
        }
 
        private int shadowOffsetX;
        public int ShadowOffsetX
        {
            get
            {
                return shadowOffsetX;
            }
            set
            {
                shadowOffsetX = value;
            }
        }
 
        private int shadowOffsetY;
        public int ShadowOffsetY
        {
            get
            {
                return shadowOffsetY;
            }
            set
            {
                shadowOffsetY = value;
            }
        }
 
        #endregion
 
        #region Contructor
 
        public Watermarker(Image originImage)
        {
            this.OriginImage = originImage;
            // 默认值
            this.ShadowColor = Color.FromArgb(153, 0, 0, 0);
            this.ForeColor = Color.FromArgb(153, 255, 255, 255);
            this.ShadowOffsetX = 1;
            this.ShadowOffsetY = 1;
            this.Position = WatermarkPostion.BottomRight;
            this.HorizontalMarginPixel = 10;
            this.VerticalMarginPixel = 10;
        }
 
        #endregion
 
        #region Methods
 
        public void SetX(float x)
        {
            this.X = x;
            computeX = false;
        }
 
        public void SetY(float y)
        {
            this.Y = y;
            computeY = false;
        }
 
        public void SetXY(float x, float y)
        {
            SetX(x);
            SetY(y);
        }
 
        /// 
        /// Add water mark to original image
        /// 
        public Image AddWatermark()
        {
            ComputeWatermarkSize();
            UpdateXY();
            watermarkedImage = AddWatermarkToOriginImage();
 
            return watermarkedImage;
        }
 
        /// 
        /// hook
        /// 
        /// 
        protected virtual SizeF ComputeWatermarkSize()
        {
            this.WatermarkSize = new SizeF(100f, 50f);
            return this.WatermarkSize;
        }
 
        /// 
        /// hook
        /// 
        protected virtual Image AddWatermarkToOriginImage()
        {
            return originImage;
        }
        
        /// 
        /// hook
        /// 
        protected virtual void UpdateXY()
        {
            if (this.ComputeX)
            {
                switch (this.HorizontalPosition)
                {
                    case WatermarkHorizontalPostion.Left:
                        this.X = this.HorizontalMarginPixel;
                        break;
 
                    case WatermarkHorizontalPostion.Center:
                        this.X = this.OriginImage.Width / 2 - this.WatermarkSize.Width / 2;
                        break;
 
                    case WatermarkHorizontalPostion.Right:
                        this.X = (this.OriginImage.Width - this.HorizontalMarginPixel - this.WatermarkSize.Width);
                        break;
 
                    default:
                        break;
                }
            }
 
            if (this.ComputeY)
            {
                switch (this.VerticalPosition)
                {
                    case WatermarkVerticalPostion.Top:
                        this.Y = this.VerticalMarginPixel;
                        break;
 
                    case WatermarkVerticalPostion.Middle:
                        this.Y = this.OriginImage.Height / 2 - this.WatermarkSize.Height / 2;
                        break;
 
                    case WatermarkVerticalPostion.Bottom:
                        this.Y = (this.OriginImage.Height - this.VerticalMarginPixel - this.WatermarkSize.Height);
                        break;
 
                    default:
                        break;
                }
            }
        }
 
        private static WatermarkHorizontalPostion GetHorizentalPosition(WatermarkPostion pos)
        {
            // Mask: 000 111
            return (WatermarkHorizontalPostion)((char)pos & (char)0x07);
        }
 
        private static WatermarkVerticalPostion GetVerticalPosition(WatermarkPostion pos)
        {
            // Mask: 111 000
            return (WatermarkVerticalPostion)((char)pos & (char)0x38);
        }
 
        private static WatermarkPostion GetPosition(WatermarkHorizontalPostion hPos, WatermarkVerticalPostion vPos)
        {
            return (WatermarkPostion)((char)hPos | (char)vPos);
        }
 
        #endregion
 
        #region IDisposable 成员
 
        public virtual void Dispose()
        {
            this.OriginImage.Dispose();
            this.WatermarkedImage.Dispose();
        }
 
        #endregion
    }
 
    public enum WatermarkPostion
    {
        TopLeft = 0x24,         // 100 100
        TopCenter = 0x22,       // 100 010
        TopRight = 0x21,        // 100 001
        MiddleLeft = 0x14,      // 010 100
        MiddleCenter = 0x12,    // 010 010
        MiddleRight = 0x11,     // 010 001    
        BottomLeft = 0x0C,      // 001 100
        BottomCenter = 0x0A,    // 001 010
        BottomRight = 0x09,     // 001 001
    }
 
    public enum WatermarkHorizontalPostion
    {
        Left = 0x04,            // 000 100
        Center = 0x02,          // 000 010
        Right = 0x01,           // 000 001
    }
 
    public enum WatermarkVerticalPostion
    {
        Top = 0x20,             // 100 000
        Middle = 0x10,          // 010 000
        Bottom = 0x08,          // 001 000
    }
}

再来分别看加图片水印的类ImageWatermarker.cs与加文本水印的类TextWatermark.cs的源码:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
 
namespace zizhujy.ImageHandler
{
    public class ImageWatermarker : Watermarker
    {
        #region Properties
 
        private Image watermarkImage;
        public Image WatermarkImage
        {
            get
            {
                return watermarkImage;
            }
            set
            {
                watermarkImage =value;
            }
        }
 
        private ImageAttributes imageAttributes = new ImageAttributes();
        public ImageAttributes ImageAttributes
        {
            get
            {
                return imageAttributes;
            }
            set
            {
                imageAttributes = value;
            }
        }
 
        private List colorMaps = new List();
        public List ColorMaps
        {
            get
            {
                return colorMaps;
            }
            set { colorMaps = value; }
        }
 
        public float[][] ColorMatrixElements
        {
            get
            {
                if (this.ColorMatrix != null)
                {
                    return new float[][] {
                        new float[] {this.ColorMatrix.Matrix00, this.ColorMatrix.Matrix01, this.ColorMatrix.Matrix02, this.ColorMatrix.Matrix03, this.ColorMatrix.Matrix04},
                        new float[] {this.ColorMatrix.Matrix10, this.ColorMatrix.Matrix11, this.ColorMatrix.Matrix12, this.ColorMatrix.Matrix13, this.ColorMatrix.Matrix14},
                        new float[] {this.ColorMatrix.Matrix20, this.ColorMatrix.Matrix21, this.ColorMatrix.Matrix22, this.ColorMatrix.Matrix23, this.ColorMatrix.Matrix24},
                        new float[] {this.ColorMatrix.Matrix30, this.ColorMatrix.Matrix31, this.ColorMatrix.Matrix32, this.ColorMatrix.Matrix33, this.ColorMatrix.Matrix34},
                        new float[] {this.ColorMatrix.Matrix40, this.ColorMatrix.Matrix41, this.ColorMatrix.Matrix42, this.ColorMatrix.Matrix43, this.ColorMatrix.Matrix44}
                    };
                }
                else
                {
                    return null;
                }
            }
            set
            {
                this.ColorMatrix.Matrix00 = value[0][0];
                this.ColorMatrix.Matrix01 = value[0][1];
                this.ColorMatrix.Matrix02 = value[0][2];
                this.ColorMatrix.Matrix03 = value[0][3];
                this.ColorMatrix.Matrix04 = value[0][4];
                this.ColorMatrix.Matrix10 = value[1][0];
                this.ColorMatrix.Matrix11 = value[1][1];
                this.ColorMatrix.Matrix12 = value[1][2];
                this.ColorMatrix.Matrix13 = value[1][3];
                this.ColorMatrix.Matrix14 = value[1][4];
                this.ColorMatrix.Matrix20 = value[2][0];
                this.ColorMatrix.Matrix21 = value[2][1];
                this.ColorMatrix.Matrix22 = value[2][2];
                this.ColorMatrix.Matrix23 = value[2][3];
                this.ColorMatrix.Matrix24 = value[2][4];
                this.ColorMatrix.Matrix30 = value[3][0];
                this.ColorMatrix.Matrix31 = value[3][1];
                this.ColorMatrix.Matrix32 = value[3][2];
                this.ColorMatrix.Matrix33 = value[3][3];
                this.ColorMatrix.Matrix34 = value[3][4];
                this.ColorMatrix.Matrix40 = value[4][0];
                this.ColorMatrix.Matrix41 = value[4][1];
                this.ColorMatrix.Matrix42 = value[4][2];
                this.ColorMatrix.Matrix43 = value[4][3];
                this.ColorMatrix.Matrix44 = value[4][4];
            }
        }
 
        private ColorMatrix colorMatrix;
        public ColorMatrix ColorMatrix
        {
            get
            {
                return colorMatrix;
            }
            set
            {
                colorMatrix = value;
            }
        }
 
        private bool keepScale;
        public bool KeepScale
        {
            get { return keepScale; }
            set { keepScale = value; }
        }
 
        public override double ForegroundOpacity
        {
            get
            {
                return base.ForegroundOpacity;
            }
            set
            {
                double percent = value > 1 ? 1 : (value < 0 ? 0 : value);
 
                base.ForegroundOpacity = percent;
                this.ColorMatrix.Matrix33 = (float)percent;
            }
        }
 
        #endregion
 
        #region Constructor
 
        public ImageWatermarker(Image originImage, Image watermarkImage)
            : base(originImage)
        {
            this.WatermarkImage = watermarkImage;
 
            // Default values
            this.ColorMaps.Add(new ColorMap());
            this.ColorMaps[0].OldColor = Color.FromArgb(255, 255, 255, 255);
            this.ColorMaps[0].NewColor = Color.FromArgb(0, 0, 0, 0);
 
            float[][] colorMatrixElements = {
                new float[]{1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
                new float[]{0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
                new float[]{0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
                new float[]{0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
                new float[]{0.0f, 0.0f, 0.0f, 0.0f, 1.0f}   
            };
            this.ColorMatrix = new ColorMatrix(colorMatrixElements);
            this.WatermarkSize = this.WatermarkImage.Size;
            this.KeepScale = true;
        }
 
        #endregion
 
        #region Methods
 
        protected override SizeF ComputeWatermarkSize()
        {
            return this.WatermarkSize;
        }
 
        protected override Image AddWatermarkToOriginImage()
        {
            this.WatermarkedImage = this.OriginImage;
            Graphics watermarkGraphic = Graphics.FromImage(this.WatermarkedImage);
 
            this.ImageAttributes.SetRemapTable(this.ColorMaps.ToArray(), ColorAdjustType.Bitmap);
            this.ImageAttributes.SetColorMatrix(this.ColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
 
            watermarkGraphic.DrawImage(this.WatermarkImage,
                new Rectangle((int)this.X, (int)this.Y, (int)this.WatermarkSize.Width, (int)this.WatermarkSize.Height),
                0, 0, this.WatermarkImage.Width, this.WatermarkImage.Height,
                GraphicsUnit.Pixel, this.ImageAttributes);
 
            watermarkGraphic.Dispose();
            imageAttributes.Dispose();
 
            return this.WatermarkedImage;
        }
 
        public void SetWatermarkWidth(int width)
        {
            float height = this.WatermarkSize.Height;
            if (this.KeepScale)
            {
                height = height * width / this.WatermarkSize.Width;
            }
 
            this.WatermarkSize = new SizeF(width, height);
        }
 
        public void SetWatermarkHeight(int height)
        {
            float width = this.WatermarkSize.Width;
            if (this.KeepScale)
            {
                width = width * height / this.WatermarkSize.Height;
            }
 
            this.WatermarkSize = new SizeF(width, height);
        }
 
        public void SetWatermarkSize(int width, int height)
        {
            this.WatermarkSize = new SizeF(width, height);
            this.KeepScale = false;
        }
 
        public override void Dispose()
        {
            base.Dispose();
            this.WatermarkImage.Dispose();
        }
 
        #endregion
    }
}

 

using System;
using System.Drawing;
using System.Collections.Generic;
 
namespace zizhujy.ImageHandler
{
    public class TextWatermarker : Watermarker
    {
        #region Properties
 
        private string watermarkText;
        public string WatermarkText
        {
            get
            {
                return watermarkText;
            }
            set
            {
                watermarkText = value;
            }
        }
 
        // 自动计算最合适的水印文本字体大小
        private bool autoSize = true;
        public bool AutoSize
        {
            get
            {
                return autoSize;
            }
            set
            {
                autoSize = value;
            }
        }
 
        private double fontSizePercent;
        public double FontSizePercent
        {
            get { return fontSizePercent; }
            set {
                fontSizePercent = value > 1 ? 1 : (value <= 0.01 ? 0.01 : value);
            }
        }
 
        private List<Font> fonts = new List<Font>();
        public List<Font> Fonts
        {
            get
            {
                return fonts;
            }
            set
            {
                fonts = value;
            }
        }
 
        private Font bestFont = new Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Pixel);
        public Font BestFont{
            get{
                return bestFont;
            }
            set
            {
                bestFont = value;
            }
        }
 
        private StringFormat StringFormat
        {
            get
            {
                StringFormat format = new StringFormat();
                if (this.ComputeX)
                {
                    switch (this.HorizontalPosition)
                    {
                        case WatermarkHorizontalPostion.Left:
                            format.Alignment = StringAlignment.Near;
                            break;
 
                        case WatermarkHorizontalPostion.Center:
                            format.Alignment = StringAlignment.Center;
                            break;
 
                        case WatermarkHorizontalPostion.Right:
                            format.Alignment = StringAlignment.Far;
                            break;
                    }
                }
                else
                {
                    format.Alignment = StringAlignment.Near;
                }
 
                return format;
            }
        }
 
        #endregion
 
        #region Constructor
 
        public TextWatermarker(Image originImage, string watermarkText) : base(originImage)
        {
            this.WatermarkText = watermarkText;
 
            // Default values
            this.Fonts.Add(new Font("Arial", 18, FontStyle.Regular, GraphicsUnit.Pixel));
            this.Fonts.Add(new Font("Arial", 16, FontStyle.Regular, GraphicsUnit.Pixel));
            this.Fonts.Add(new Font("Arial", 14, FontStyle.Regular, GraphicsUnit.Pixel));
            this.Fonts.Add(new Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Pixel));
            this.Fonts.Add(new Font("Arial", 10, FontStyle.Regular, GraphicsUnit.Pixel));
            this.Fonts.Add(new Font("Arial", 8, FontStyle.Regular, GraphicsUnit.Pixel));
            this.Fonts.Add(new Font("Arial", 6, FontStyle.Regular, GraphicsUnit.Pixel));
            this.Fonts.Add(new Font("Arial", 4, FontStyle.Regular, GraphicsUnit.Pixel));
            this.FontSizePercent = 30.00 / 480.00;
            this.AutoSize = true;
        }
 
        #endregion
 
        #region Methods

        public void ChangeFontFamily(string fontFamily)
        {
            FontFamily ff = new FontFamily(fontFamily);
            for (int i = 0; i < this.Fonts.Count; i++)
            {
                this.Fonts[i] = new Font(ff, this.Fonts[i].Size, this.Fonts[i].Style, this.Fonts[i].Unit, this.Fonts[i].GdiCharSet, this.Fonts[i].GdiVerticalFont);
            }
            this.BestFont = new Font(ff, this.BestFont.Size, this.BestFont.Style, this.BestFont.Unit, this.BestFont.GdiCharSet, this.BestFont.GdiVerticalFont);
        }
 
        protected override SizeF ComputeWatermarkSize()
        {
            FindAvailableMaxSizedFont();
            return this.WatermarkSize;
        }
 
        protected override void UpdateXY()
        {
            if (this.ComputeX)
            {
                switch (this.HorizontalPosition)
                {
                    case WatermarkHorizontalPostion.Left:
                        this.X = this.HorizontalMarginPixel;
                        break;
 
                    case WatermarkHorizontalPostion.Center:
                        this.X = this.OriginImage.Width / 2;
                        break;
 
                    case WatermarkHorizontalPostion.Right:
                        this.X = (this.OriginImage.Width - this.HorizontalMarginPixel);
                        break;
 
                    default:
                        break;
                }
            }
 
            if (this.ComputeY)
            {
                switch (this.VerticalPosition)
                {
                    case WatermarkVerticalPostion.Top:
                        this.Y = this.VerticalMarginPixel;
                        break;
 
                    case WatermarkVerticalPostion.Middle:
                        this.Y = this.OriginImage.Height / 2 - this.WatermarkSize.Height / 2;
                        break;
 
                    case WatermarkVerticalPostion.Bottom:
                        this.Y = (this.OriginImage.Height - this.VerticalMarginPixel - this.WatermarkSize.Height);
                        break;
 
                    default:
                        break;
                }
            }
        }
 
        protected override Image AddWatermarkToOriginImage()
        {
            this.WatermarkedImage = this.OriginImage;
            Graphics g = Graphics.FromImage(this.WatermarkedImage);
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            SolidBrush semiTransBrushShadow = new SolidBrush(this.ShadowColor);
            
            StringFormat format = this.StringFormat;
            g.DrawString(this.WatermarkText, this.BestFont, semiTransBrushShadow, new PointF(this.X + this.ShadowOffsetX, this.Y + this.ShadowOffsetY), format);
            SolidBrush semiTransBrush = new SolidBrush(this.ForeColor);
            g.DrawString(this.WatermarkText, this.BestFont, semiTransBrush, new PointF(this.X, this.Y), format);
            g.Dispose();
 
            return this.WatermarkedImage;
        }
 
        private Font FindAvailableMaxSizedFont()
        {
            if (this.AutoSize)
            {
                this.BestFont = FindAvailableMaxSizedFont(false);
                if (this.BestFont.Size >= 16)
                {
                    return this.BestFont;
                }
                else
                {
                    return FindAvailableMaxSizedFont(true); 
                }
            }
            else
            {
                return FindAvailableMaxSizedFont(true);
            }
        }
 
        private Font FindAvailableMaxSizedFont(bool byAbsoluteSizes)
        {
            if (byAbsoluteSizes)
            {
                this.Fonts.Sort(delegate(Font font1, Font font2) { return font2.Size.CompareTo(font1.Size); });
                SizeF size = new SizeF();
                Bitmap image = new Bitmap(1, 1);
                Graphics g = Graphics.FromImage(image);
 
                for (int i = 0; i < this.Fonts.Count; i++)
                {
                    //size = MeasureSize(this.WatermarkText, this.Fonts[i]);
                    size = g.MeasureString(this.WatermarkText, this.Fonts[i]);
                    if ((ushort)(size.Width + this.HorizontalMarginPixel * 2) < (ushort)this.OriginImage.Width && (ushort)(size.Height + this.VerticalMarginPixel * 2) < (ushort)this.OriginImage.Height)
                    {
                        g.Dispose();
                        image.Dispose();
                        this.WatermarkSize = size;
                        this.BestFont = this.fonts[i];
                        return this.Fonts[i];
                    }
                }
 
                g.Dispose();
                image.Dispose();
 
                this.WatermarkSize = new SizeF(0, 0);
                return null;
            }
            else
            {
                int fontSize = (int)(this.OriginImage.Height * this.FontSizePercent);
                fontSize = fontSize >= 1 ? fontSize : 1;
                this.BestFont = new Font(this.BestFont.FontFamily, fontSize, this.BestFont.Style, this.BestFont.Unit);
                this.WatermarkSize = MeasureSize(this.WatermarkText, this.BestFont);
                if ((ushort)(this.WatermarkSize.Width + this.HorizontalMarginPixel * 2) < (ushort)this.OriginImage.Width && (ushort)(this.WatermarkSize.Height + this.VerticalMarginPixel * 2) < (ushort)this.OriginImage.Height)
                {
                    return this.BestFont;
                }
                else
                {
                    this.WatermarkSize = new SizeF(0, 0);
                    return null;
                }
            }
        }
 
        private SizeF MeasureSize(string text, Font font)
        {
            // Use a test image to measure the text.
            Bitmap image = new Bitmap(1, 1);
            Graphics g = Graphics.FromImage(image);
            SizeF size = g.MeasureString(text, font);
            g.Dispose();
            image.Dispose();
 
            return size;
        }
 
        #endregion
    }
}
 

 

四、总结:

这里采用模板设计模式,可复用性高,能被引用在多种工程之中;可扩展性强,比如当有需要添加HTML水印时,只需要新建一个HtmlWatermarker类,并实现模板类Watermarker中的相关方法即可,不需要更改任何现有代码。

注意,模板设计模式很好地遵循了面向对象设计中的一个重要原则:对修改关闭,对扩展开放。

五、相关文件下载:

DLL 文件(若仅需使用):ImageHandler.dll (18.00 kb)

整个项目文件(若还需开发):ImageHandler.rar (45.03 kb)

 

[donate: www.zizhujy.com]

Add comment

Loading