轉:圖片水印 文字水印 實例

/*
 * Class:WaterImage
 * Use for add a water Image to the picture both words and image
 * 2007.07.23   create the file
 *
 *
 * 使用說明:
 *  建議先定義一個WaterImage實例
 *  然後利用實例的屬性,去匹配需要進行操作的參數
 *  然後定義一個WaterImageManage實例
 *  利用WaterImageManage實例進行DrawImage(),印圖片水印
 *  DrawWords()印文字水印
 *
-*/

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
/// <summary>
/// 圖片位置
/// </summary>
public enum ImagePosition
{
    LeftTop,        //左上
    LeftBottom,    //左下
    RightTop,       //右上
    RigthBottom,  //右下
    TopMiddle,     //頂部居中
    BottomMiddle, //底部居中
    Center           //中心
}

/// <summary>
/// 水印圖片的操作管理 Design by Gary Gong From Demetersoft.com
/// </summary>
public class WaterImageManage
{
    /// <summary>
    /// 生成一個新的水印圖片製作實例
    /// </summary>
    public WaterImageManage()
    {
        //
        // TODO: Add constructor logic here
        //
    }

    /// <summary>
    /// 添加圖片水印
    /// </summary>
    /// <param name="sourcePicture">源圖片文件名</param>
    /// <param name="waterImage">水印圖片文件名</param>
    /// <param name="alpha">透明度(0.1-1.0數值越小透明度越高)</param>
    /// <param name="position">位置</param>
    /// <param name="PicturePath" >圖片的路徑</param>
    /// <returns>返回生成於指定文件夾下的水印文件名</returns>
    public string DrawImage(string sourcePicture,
                                      string waterImage,
                                      float alpha,
                                      ImagePosition position,
                                      string PicturePath)
    {
        //
        // 判斷參數是否有效
        //
        if (sourcePicture == string.Empty || waterImage == string.Empty || alpha == 0.0 || PicturePath == string.Empty)
        {
            return sourcePicture;
        }

        //
        // 源圖片,水印圖片全路徑
        //
        string sourcePictureName = PicturePath + sourcePicture;
        string waterPictureName = PicturePath + waterImage;
        string fileSourceExtension = System.IO.Path.GetExtension(sourcePictureName).ToLower();
        string fileWaterExtension = System.IO.Path.GetExtension(waterPictureName).ToLower();
        //
        // 判斷文件是否存在,以及類型是否正確
        //
        if (System.IO.File.Exists(sourcePictureName) == false ||
            System.IO.File.Exists(waterPictureName) == false || (
            fileSourceExtension != ".gif" &&
            fileSourceExtension != ".jpg" &&
            fileSourceExtension != ".png") || (
            fileWaterExtension != ".gif" &&
            fileWaterExtension != ".jpg" &&
            fileWaterExtension != ".png")
            )
        {
            return sourcePicture;
        }

        //
        // 目標圖片名稱及全路徑
        //
        string targetImage = sourcePictureName.Replace(System.IO.Path.GetExtension(sourcePictureName), "") + "_1101.jpg";

        //
        // 將需要加上水印的圖片裝載到Image對象中
        //
        Image imgPhoto = Image.FromFile(sourcePictureName);
        //
        // 確定其長寬
        //
        int phWidth = imgPhoto.Width;
        int phHeight = imgPhoto.Height;

        //
        // 封裝 GDI+ 位圖,此位圖由圖形圖像及其屬性的像素數據組成。
        //
        Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);

        //
        // 設定分辨率
        //
        bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

        //
        // 定義一個繪圖畫面用來裝載位圖
        //
        Graphics grPhoto = Graphics.FromImage(bmPhoto);

        //
        //同樣,由於水印是圖片,我們也需要定義一個Image來裝載它
        //
        Image imgWatermark = new Bitmap(waterPictureName);

        //
        // 獲取水印圖片的高度和寬度
        //
        int wmWidth = imgWatermark.Width;
        int wmHeight = imgWatermark.Height;

        //SmoothingMode:指定是否將平滑處理(消除鋸齒)應用於直線、曲線和已填充區域的邊緣。
        // 成員名稱   說明
        // AntiAlias      指定消除鋸齒的呈現。 
        // Default        指定不消除鋸齒。 
        // HighQuality  指定高質量、低速度呈現。 
        // HighSpeed   指定高速度、低質量呈現。 
        // Invalid        指定一個無效模式。 
        // None          指定不消除鋸齒。
        grPhoto.SmoothingMode = SmoothingMode.AntiAlias;

        //
        // 第一次描繪,將我們的底圖描繪在繪圖畫面上
        //
        grPhoto.DrawImage(imgPhoto,
                                    new Rectangle(0, 0, phWidth, phHeight),
                                    0,
                                    0,
                                    phWidth,
                                    phHeight,
                                    GraphicsUnit.Pixel);

        //
        // 與底圖一樣,我們需要一個位圖來裝載水印圖片。並設定其分辨率
        //
        Bitmap bmWatermark = new Bitmap(bmPhoto);
        bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

        //
        // 繼續,將水印圖片裝載到一個繪圖畫面grWatermark
        //
        Graphics grWatermark = Graphics.FromImage(bmWatermark);

        //
        //ImageAttributes 對象包含有關在呈現時如何操作位圖和圖元文件顏色的信息。
        //      
        ImageAttributes imageAttributes = new ImageAttributes();

        //
        //Colormap: 定義轉換顏色的映射
        //
        ColorMap colorMap = new ColorMap();

        //
        //我的水印圖被定義成擁有綠色背景色的圖片被替換成透明
        //
        colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
        colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);

        ColorMap[] remapTable = { colorMap };

        imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

        float[][] colorMatrixElements = {
           new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f}, // red紅色
           new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f}, //green綠色
           new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f}, //blue藍色      
           new float[] {0.0f,  0.0f,  0.0f,  alpha, 0.0f}, //透明度    
           new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}};//

        //  ColorMatrix:定義包含 RGBA 空間座標的 5 x 5 矩陣。
        //  ImageAttributes 類的若干方法通過使用顏色矩陣調整圖像顏色。
        ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);


        imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default,
         ColorAdjustType.Bitmap);

        //
        //上面設置完顏色,下面開始設置位置
        //
        int xPosOfWm;
        int yPosOfWm;

        switch (position)
        {
            case ImagePosition.BottomMiddle:
                xPosOfWm = (phWidth - wmWidth) / 2;
                yPosOfWm = phHeight - wmHeight - 10;
                break;
            case ImagePosition.Center:
                xPosOfWm = (phWidth - wmWidth) / 2;
                yPosOfWm = (phHeight - wmHeight) / 2;
                break;
            case ImagePosition.LeftBottom:
                xPosOfWm = 10;
                yPosOfWm = phHeight - wmHeight - 10;
                break;
            case ImagePosition.LeftTop:
                xPosOfWm = 10;
                yPosOfWm = 10;
                break;
            case ImagePosition.RightTop:
                xPosOfWm = phWidth - wmWidth - 10;
                yPosOfWm = 10;
                break;
            case ImagePosition.RigthBottom:
                xPosOfWm = phWidth - wmWidth - 10;
                yPosOfWm = phHeight - wmHeight - 10;
                break;
            case ImagePosition.TopMiddle:
                xPosOfWm = (phWidth - wmWidth) / 2;
                yPosOfWm = 10;
                break;
            default:
                xPosOfWm = 10;
                yPosOfWm = phHeight - wmHeight - 10;
                break;
        }

        //
        // 第二次繪圖,把水印印上去
        //
        grWatermark.DrawImage(imgWatermark,
         new Rectangle(xPosOfWm,
                             yPosOfWm,
                             wmWidth,
                             wmHeight),
                             0,
                             0,
                             wmWidth,
                             wmHeight,
                             GraphicsUnit.Pixel,
                             imageAttributes);


        imgPhoto = bmWatermark;
        grPhoto.Dispose();
        grWatermark.Dispose();

        //
        // 保存文件到服務器的文件夾裏面
        //
        imgPhoto.Save(targetImage, ImageFormat.Jpeg);
        imgPhoto.Dispose();
        imgWatermark.Dispose();
        return targetImage.Replace(PicturePath, "");
    }

    /// <summary>
    /// 在圖片上添加水印文字
    /// </summary>
    /// <param name="sourcePicture">源圖片文件</param>
    /// <param name="waterWords">需要添加到圖片上的文字</param>
    /// <param name="alpha">透明度</param>
    /// <param name="position">位置</param>
    /// <param name="PicturePath">文件路徑</param>
    /// <returns></returns>
    public string DrawWords(string sourcePicture,
                                      string waterWords,
                                      float alpha,
                                      ImagePosition position,
                                      string PicturePath)
    {
        //
        // 判斷參數是否有效
        //
        if (sourcePicture == string.Empty || waterWords == string.Empty || alpha == 0.0 || PicturePath == string.Empty)
        {
            return sourcePicture;
        }

        //
        // 源圖片全路徑
        //
        string sourcePictureName = PicturePath + sourcePicture;
        string fileExtension = System.IO.Path.GetExtension(sourcePictureName).ToLower();

        //
        // 判斷文件是否存在,以及文件名是否正確
        //
        if (System.IO.File.Exists(sourcePictureName) == false || (
            fileExtension != ".gif" &&
            fileExtension != ".jpg" &&
            fileExtension != ".png"))
        {
            return sourcePicture;
        }

        //
        // 目標圖片名稱及全路徑
        //
        string targetImage = sourcePictureName.Replace(System.IO.Path.GetExtension(sourcePictureName), "") + "_0703.jpg";

        //創建一個圖片對象用來裝載要被添加水印的圖片
        Image imgPhoto = Image.FromFile(sourcePictureName);

        //獲取圖片的寬和高
        int phWidth = imgPhoto.Width;
        int phHeight = imgPhoto.Height;

        //
        //建立一個bitmap,和我們需要加水印的圖片一樣大小
        Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);

        //SetResolution:設置此 Bitmap 的分辨率
        //這裏直接將我們需要添加水印的圖片的分辨率賦給了bitmap
        bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

        //Graphics:封裝一個 GDI+ 繪圖圖面。
        Graphics grPhoto = Graphics.FromImage(bmPhoto);

        //設置圖形的品質
        grPhoto.SmoothingMode = SmoothingMode.AntiAlias;

        //將我們要添加水印的圖片按照原始大小描繪(複製)到圖形中
        grPhoto.DrawImage(
         imgPhoto,                                           //   要添加水印的圖片
         new Rectangle(0, 0, phWidth, phHeight), //  根據要添加的水印圖片的寬和高
         0,                                                     //  X方向從0點開始描繪
         0,                                                     // Y方向
         phWidth,                                            //  X方向描繪長度
         phHeight,                                           //  Y方向描繪長度
         GraphicsUnit.Pixel);                              // 描繪的單位,這裏用的是像素

        //根據圖片的大小我們來確定添加上去的文字的大小
        //在這裏我們定義一個數組來確定
        int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 };

        //字體
        Font crFont = null;
        //矩形的寬度和高度,SizeF有三個屬性,分別爲Height高,width寬,IsEmpty是否爲空
        SizeF crSize = new SizeF();

        //利用一個循環語句來選擇我們要添加文字的型號
        //直到它的長度比圖片的寬度小
        for (int i = 0; i < 7; i++)
        {
            crFont = new Font("arial", sizes[i], FontStyle.Bold);

            //測量用指定的 Font 對象繪製並用指定的 StringFormat 對象格式化的指定字符串。
            crSize = grPhoto.MeasureString(waterWords, crFont);

            // ushort 關鍵字表示一種整數數據類型
            if ((ushort)crSize.Width < (ushort)phWidth)
                break;
        }

        //截邊5%的距離,定義文字顯示(由於不同的圖片顯示的高和寬不同,所以按百分比截取)
        int yPixlesFromBottom = (int)(phHeight * .05);

        //定義在圖片上文字的位置
        float wmHeight = crSize.Height;
        float wmWidth = crSize.Width;

        float xPosOfWm;
        float yPosOfWm;

        switch (position)
        {
            case ImagePosition.BottomMiddle:
                xPosOfWm = phWidth / 2;
                yPosOfWm = phHeight - wmHeight - 10;
                break;
            case ImagePosition.Center:
                xPosOfWm = phWidth / 2;
                yPosOfWm = phHeight / 2;
                break;
            case ImagePosition.LeftBottom:
                xPosOfWm = wmWidth;
                yPosOfWm = phHeight - wmHeight - 10;
                break;
            case ImagePosition.LeftTop:
                xPosOfWm = wmWidth / 2;
                yPosOfWm = wmHeight / 2;
                break;
            case ImagePosition.RightTop:
                xPosOfWm = phWidth - wmWidth - 10;
                yPosOfWm = wmHeight;
                break;
            case ImagePosition.RigthBottom:
                xPosOfWm = phWidth - wmWidth - 10;
                yPosOfWm = phHeight - wmHeight - 10;
                break;
            case ImagePosition.TopMiddle:
                xPosOfWm = phWidth / 2;
                yPosOfWm = wmWidth;
                break;
            default:
                xPosOfWm = wmWidth;
                yPosOfWm = phHeight - wmHeight - 10;
                break;
        }

        //封裝文本佈局信息(如對齊、文字方向和 Tab 停靠位),顯示操作(如省略號插入和國家標準 (National) 數字替換)和 OpenType 功能。
        StringFormat StrFormat = new StringFormat();

        //定義需要印的文字居中對齊
        StrFormat.Alignment = StringAlignment.Center;

        //SolidBrush:定義單色畫筆。畫筆用於填充圖形形狀,如矩形、橢圓、扇形、多邊形和封閉路徑。
        //這個畫筆爲描繪陰影的畫筆,呈灰色
        int m_alpha = Convert.ToInt32(256 * alpha);
        SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(m_alpha, 0, 0, 0));

        //描繪文字信息,這個圖層向右和向下偏移一個像素,表示陰影效果
        //DrawString 在指定矩形並且用指定的 Brush 和 Font 對象繪製指定的文本字符串。
        grPhoto.DrawString(waterWords,                                    //string of text
                                   crFont,                                         //font
                                   semiTransBrush2,                            //Brush
                                   new PointF(xPosOfWm + 1, yPosOfWm + 1),  //Position
                                   StrFormat);

        //從四個 ARGB 分量(alpha、紅色、綠色和藍色)值創建 Color 結構,這裏設置透明度爲153
        //這個畫筆爲描繪正式文字的筆刷,呈白色
        SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));

        //第二次繪製這個圖形,建立在第一次描繪的基礎上
        grPhoto.DrawString(waterWords,                 //string of text
                                   crFont,                                   //font
                                   semiTransBrush,                           //Brush
                                   new PointF(xPosOfWm, yPosOfWm),  //Position
                                   StrFormat);

        //imgPhoto是我們建立的用來裝載最終圖形的Image對象
        //bmPhoto是我們用來製作圖形的容器,爲Bitmap對象
        imgPhoto = bmPhoto;
        //釋放資源,將定義的Graphics實例grPhoto釋放,grPhoto功德圓滿
        grPhoto.Dispose();

        //將grPhoto保存
        imgPhoto.Save(targetImage, ImageFormat.Jpeg);
        imgPhoto.Dispose();

        return targetImage.Replace(PicturePath, "");
    }
}

/// <summary>
/// 裝載水印圖片的相關信息
/// </summary>
public class WaterImage
{
    public WaterImage()
    {

    }

    private string m_sourcePicture;
    /// <summary>
    /// 源圖片地址名字(帶後綴)
    /// </summary>
    public string SourcePicture
    {
        get { return m_sourcePicture; }
        set { m_sourcePicture = value; }
    }

    private string m_waterImager;
    /// <summary>
    /// 水印圖片名字(帶後綴)
    /// </summary>
    public string WaterPicture
    {
        get { return m_waterImager; }
        set { m_waterImager = value; }
    }

    private float m_alpha;
    /// <summary>
    /// 水印圖片文字的透明度
    /// </summary>
    public float Alpha
    {
        get { return m_alpha; }
        set { m_alpha = value; }
    }

    private ImagePosition m_postition;
    /// <summary>
    /// 水印圖片或文字在圖片中的位置
    /// </summary>
    public ImagePosition Position
    {
        get { return m_postition; }
        set { m_postition = value; }
    }

    private string m_words;
    /// <summary>
    /// 水印文字的內容
    /// </summary>
    public string Words
    {
        get { return m_words; }
        set { m_words = value; }
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章