首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 圖片浮水印實作教學:文字與圖片雙重浮水印完整範例

     編輯:關於C語言

前言

在圖片版權保護、品牌標識等場景中,加入浮水印是常見需求。C# System.Drawing 命名空間提供強大的 GDI+ 繪圖功能,可實作文字浮水印與圖片浮水印的疊加。本文提供完整可執行的範例程式碼,涵蓋字型自動縮放、陰影效果、半透明度控制、圖片背景透明化等實用技巧。

核心概念

  • Graphics 物件:繪圖介面,所有繪製操作透過它進行。
  • Bitmap:記憶體中的點陣圖,支援像素級操作。
  • ImageAttributes:控制繪製時的色彩轉換、透明度矩陣等。
  • ColorMatrix:5x5 矩陣調整 RGBA 色彩通道,實現透明度控制。

完整實作程式碼

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

namespace WaterMarkDemo
{
    class WaterMark
    {
        [STAThread]
        static void Main(string[] args)
        {
            // === 設定工作目錄與素材路徑 ===
            string workingDir = @"C:\Projects\WaterMark";
            string photoPath = Path.Combine(workingDir, "watermark_photo.jpg");
            string watermarkPath = Path.Combine(workingDir, "watermark.bmp");
            string outputPath = Path.Combine(workingDir, "watermark_final.jpg");

            // === 載入原始照片 ===
            using (Image imgPhoto = Image.FromFile(photoPath))
            {
                int phWidth = imgPhoto.Width;
                int phHeight = imgPhoto.Height;

                // 建立與原圖同尺寸的 Bitmap 作為畫布
                using (Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb))
                {
                    bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
                    using (Graphics grPhoto = Graphics.FromImage(bmPhoto))
                    {
                        // 設定高品質繪圖
                        grPhoto.SmoothingMode = SmoothingMode.AntiAlias;
                        grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;

                        // 將原圖繪製到畫布
                        grPhoto.DrawImage(imgPhoto, 
                            new Rectangle(0, 0, phWidth, phHeight),
                            0, 0, phWidth, phHeight, GraphicsUnit.Pixel);

                        // ==========================================
                        // 步驟 1:繪製文字浮水印(版權資訊)
                        // ==========================================
                        string copyright = "Copyright © 2024 - My Company";
                        
                        // 自動尋找適合圖片寬度的最大字型大小
                        int[] fontSizes = { 48, 36, 28, 24, 20, 16, 14, 12, 10 };
                        Font crFont = null;
                        SizeF crSize = SizeF.Empty;

                        foreach (int size in fontSizes)
                        {
                            using (Font testFont = new Font("Arial", size, FontStyle.Bold))
                            {
                                crSize = grPhoto.MeasureString(copyright, testFont);
                                if (crSize.Width < phWidth * 0.9) // 留 10% 邊距
                                {
                                    crFont = new Font("Arial", size, FontStyle.Bold);
                                    break;
                                }
                            }
                        }
                        if (crFont == null) crFont = new Font("Arial", 10, FontStyle.Bold);

                        // 計算置中下方位置(距底部 5%)
                        int yPixelsFromBottom = (int)(phHeight * 0.05);
                        float yPos = (phHeight - yPixelsFromBottom) - (crSize.Height / 2);
                        float xCenter = phWidth / 2f;

                        StringFormat strFormat = new StringFormat { Alignment = StringAlignment.Center };

                        // 陰影效果:先畫深色偏移 1 像素
                        using (SolidBrush shadowBrush = new SolidBrush(Color.FromArgb(153, 0, 0, 0)))
                        {
                            grPhoto.DrawString(copyright, crFont, shadowBrush, 
                                new PointF(xCenter + 1, yPos + 1), strFormat);
                        }

                        // 主文字:半透明白色
                        using (SolidBrush mainBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255)))
                        {
                            grPhoto.DrawString(copyright, crFont, mainBrush, 
                                new PointF(xCenter, yPos), strFormat);
                        }

                        // ==========================================
                        // 步驟 2:疊加圖片浮水印(Logo)
                        // ==========================================
                        using (Image imgWatermark = new Bitmap(watermarkPath))
                        {
                            int wmWidth = imgWatermark.Width;
                            int wmHeight = imgWatermark.Height;

                            // 建立新 Bitmap 承接已含文字浮水印的畫面
                            using (Bitmap bmWatermark = new Bitmap(bmPhoto))
                            {
                                bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
                                using (Graphics grWatermark = Graphics.FromImage(bmWatermark))
                                {
                                    // 設定 ImageAttributes 實現兩階段色彩轉換
                                    using (ImageAttributes imageAttr = new ImageAttributes())
                                    {
                                        // 階段 1:將浮水印圖片的特定背景色(此處為純綠 #00FF00)轉為全透明
                                        ColorMap colorMap = new ColorMap
                                        {
                                            OldColor = Color.FromArgb(255, 0, 255, 0),  // 綠色背景
                                            NewColor = Color.FromArgb(0, 0, 0, 0)       // 全透明
                                        };
                                        imageAttr.SetRemapTable(new[] { colorMap }, ColorAdjustType.Bitmap);

                                        // 階段 2:ColorMatrix 控制整體不透明度(0.3 = 30% 不透明)
                                        float[][] matrixElements = {
                                            new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // R
                                            new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, // G
                                            new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, // B
                                            new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f}, // Alpha (關鍵:0.3f)
                                            new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}  // W
                                        };
                                        ColorMatrix wmColorMatrix = new ColorMatrix(matrixElements);
                                        imageAttr.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

                                        // 計算右上角位置(留 10 像素邊距)
                                        int xPos = (phWidth - wmWidth) - 10;
                                        int yPosWm = 10;

                                        // 繪製浮水印圖片
                                        grWatermark.DrawImage(imgWatermark,
                                            new Rectangle(xPos, yPosWm, wmWidth, wmHeight),
                                            0, 0, wmWidth, wmHeight,
                                            GraphicsUnit.Pixel,
                                            imageAttr);
                                    }
                                }

                                // 儲存最終結果
                                bmWatermark.Save(outputPath, ImageFormat.Jpeg);
                                Console.WriteLine($"浮水印已套用,輸出:{outputPath}");
                            }
                        }
                    }
                }
            }
        }
    }
}

關鍵技術解析

1. 文字浮水印自適應字型大小

透過迴圈嘗試不同字型大小,配合 Graphics.MeasureString 測量寬度,選擇不超過圖片寬度 90% 的最大字型,確保各尺寸圖片都能完整顯示版權文字。

2. 陰影效果實現立體感

先以深色半透明筆刷(Alpha=153)繪製偏移 (1,1) 的文字,再繪製主體白色文字,形成微妙陰影,提升在複雜背景下的可讀性。

3. 圖片浮水印透明化雙重處理

  • ColorMap 重對應:將浮水印素材圖片的特定背景色(範例使用純綠)替換為全透明,實現非矩形 Logo。
  • ColorMatrix Alpha 縮放:矩陣第 4 行第 4 欄設為 0.3f,將整體不透明度降至 30%,達到半透明浮水印效果。

4. 資源管理與記憶體釋放

所有實作 IDisposable 的 GDI+ 物件(Bitmap、Graphics、Font、Brush、ImageAttributes)均以 using 區塊包裹,確保非受控資源及時釋放,避免 GDI+ 物件洩漏導致「generic error」例外。

常見問題與調整建議

需求調整方式
改變浮水印位置修改 xPos、yPosWm 計算邏輯(置中、左下、平鋪等)
調整透明度修改 ColorMatrix 中的 0.3f 數值(0.0~1.0)
浮水印素材非綠背景修改 ColorMap.OldColor 對應實際背景色
支援 PNG 透明通道素材可省略 ColorMap 步驟,直接使用 ColorMatrix 控制整體透明度
輸出格式變更 ImageFormat.Jpeg 為 Png、Bmp 等

總結

透過 System.Drawing 的 Graphics、Bitmap、ImageAttributes 與 ColorMatrix 組合,可實作專業級的雙重浮水印功能。關鍵在於:文字自適應排版、陰影增強可讀性、圖片背景透明化與 Alpha 混合兩階段處理、嚴謹的資源釋放。此範例可直接整合至批次處理服務、上傳處理管線或桌面應用程式中。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved