本文以一個完整實例講述了C#水印圖片的生成方法。是非常實用的技巧。分享給大家供大家參考。
具體實例代碼如下:
/** * 使用說明:* 建議先定義一個WaterImage實例* 然后利用實例的屬性,去匹配需要進行操作的參數* 然后定義一個WaterImageManage實例* 利用WaterImageManage實例進行DrawImage(),印圖片水印* DrawWords()印文字水印* */using System;using System.Drawing;using System.Drawing.Imaging;using System.Drawing.Drawing2D;using System.IO;namespace ABC{ /// <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, ""); }/** * 使用說明:* 建議先定義一個WaterImage實例* 然后利用實例的屬性,去匹配需要進行操作的參數* 然后定義一個WaterImageManage實例* 利用WaterImageManage實例進行DrawImage(),印圖片水印* DrawWords()印文字水印* -*/ /// <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; } // // 源圖片全路徑 // if (PicturePath.Substring(PicturePath.Length - 1, 1) != "/") PicturePath += "/"; 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; } } }}
相信本文所述對大家的C#程序設計有一定的借鑒參考作用。
新聞熱點
疑難解答