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

PHP 圖片水印功能完整實現(支援 PNG/JPG/GIF)

     編輯:PHP 相關知識

為圖片添加水印是保護版權、品牌推廣的常見需求。本文提供一個健壯、可復用的 img_water_mark() 函數,支援主流圖片格式、9 種定位模式、透明度控制,並包含完善的錯誤碼返回機制。

核心函數:img_water_mark()

<?php
/**
 * 圖片加水印(支援 png/jpg/gif)
 *
 * @param string $srcImg     原圖路徑
 * @param string $waterImg   水印圖路徑
 * @param string $savepath   保存目錄(預設同原圖目錄)
 * @param string $savename   保存檔名(預設同原圖檔名)
 * @param int    $position   水印位置 1~9(參見下方說明)
 * @param int    $alpha      透明度 0~100(0 全透明,100 不透明)
 * @return string|int  成功返回新圖路徑,失敗返回負數錯誤碼
 */
function img_water_mark($srcImg, $waterImg, $savepath = null, $savename = null, $position = 5, $alpha = 30) {
    // 1. 解析原圖路徑資訊
    $info = pathinfo($srcImg);
    $name = $info['basename'];
    $dir  = $info['dirname'];
    $ext  = $info['extension'];

    $savename = $savename ?: $name;
    $savepath = $savepath ?: $dir;
    $savefile = $savepath . '/' . $savename;

    // 2. 取得圖片尺寸與類型
    $srcInfo   = @getimagesize($srcImg);
    $waterInfo = @getimagesize($waterImg);

    if (!$srcInfo)   return -1; // 原文件不存在
    if (!$waterInfo) return -2; // 水印文件不存在

    // 3. 建立 GD 圖像資源
    $srcObj   = image_create_from_ext($srcImg);
    $waterObj = image_create_from_ext($waterImg);

    if (!$srcObj)   return -3; // 原圖資源建立失敗
    if (!$waterObj) return -4; // 水印資源建立失敗

    // 4. 計算水印座標(9 宮格定位)
    $srcW = $srcInfo[0];  $srcH = $srcInfo[1];
    $watW = $waterInfo[0]; $watH = $waterInfo[1];

    switch ($position) {
        case 1: $x = 0;              $y = 0;                 break; // 左上
        case 2: $x = $srcW - $watW;  $y = 0;                 break; // 右上
        case 3: $x = ($srcW - $watW)/2; $y = ($srcH - $watH)/2; break; // 居中
        case 4: $x = 0;              $y = $srcH - $watH;     break; // 左下
        case 5: $x = $srcW - $watW;  $y = $srcH - $watH;     break; // 右下(預設)
        case 6: $x = ($srcW - $watW)/2; $y = 0;                 break; // 頂部居中
        case 7: $x = ($srcW - $watW)/2; $y = $srcH - $watH;     break; // 底部居中
        case 8: $x = 0;              $y = ($srcH - $watH)/2;     break; // 左側居中
        case 9: $x = $srcW - $watW;  $y = ($srcH - $watH)/2;     break; // 右側居中
        default: $x = $y = 0;
    }

    // 5. 合併圖片(支援透明度)
    imagecopymerge($srcObj, $waterObj, $x, $y, 0, 0, $watW, $watH, $alpha);

    // 6. 按原格式輸出
    switch ($srcInfo[2]) {
        case IMAGETYPE_GIF:  imagegif($srcObj, $savefile);  break;
        case IMAGETYPE_JPEG: imagejpeg($srcObj, $savefile); break;
        case IMAGETYPE_PNG:  imagepng($srcObj, $savefile);  break;
        default: return -5; // 不支援格式
    }

    // 7. 釋放資源
    imagedestroy($srcObj);
    imagedestroy($waterObj);

    return $savefile;
}

/**
 * 根據副檔名/MIME 建立 GD 資源
 */
function image_create_from_ext($imgfile) {
    $info = @getimagesize($imgfile);
    if (!$info) return null;

    switch ($info[2]) {
        case IMAGETYPE_GIF:  return imagecreatefromgif($imgfile);
        case IMAGETYPE_JPEG: return imagecreatefromjpeg($imgfile);
        case IMAGETYPE_PNG:  return imagecreatefrompng($imgfile);
        default: return null;
    }
}
?>

使用範例

<?php
// 右下角、透明度 50%、另存為新檔
$result = img_water_mark(
    'uploads/photo.jpg',
    'assets/watermark.png',
    'uploads/watermarked',
    'photo_wm.jpg',
    5,   // 位置:右下
    50   // 透明度 50%
);

if (is_int($result) && $result < 0) {
    $errors = [
        -1 => '原圖不存在', -2 => '水印圖不存在',
        -3 => '原圖資源建立失敗', -4 => '水印資源建立失敗', -5 => '儲存失敗'
    ];
    exit('錯誤:' . $errors[$result]);
}
echo '水印已生成:' . $result;
?>

關鍵技術點解析

  • 格式自動識別:使用 getimagesize() 返回的索引 2(IMAGETYPE_* 常量)判斷格式,避免副檔名欺騙。
  • 透明度處理:imagecopymerge() 最後一個參數控制不透明度(0~100),PNG 水印若本身含 Alpha 通道效果更佳。
  • 錯誤碼設計:負數區分具體失敗階段,便於上層業務精準處理。
  • 資源釋放:imagedestroy() 防止記憶體洩漏,批量處理時尤為重要。

常見問題與優化

  1. GIF 動畫水印:GD 僅處理第一幀,需用 ImageMagick 或 ffmpeg 處理動圖。
  2. 大圖記憶體溢出:調大 memory_limit 或分塊處理。
  3. 文字水印:改用 imagettftext() 繪製 TTF 字體文字,支援中文、旋轉、陰影。
  4. 批量處理:遍歷目錄配合 glob(),建議加入進度條與錯誤日誌。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved