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

PHP 圖片處理:使用 imagecopy 添加圖片水印

     編輯:PHP 綜合知識

為何需要圖片水印?

數位內容易被盜用,水印是宣示版權、阻嚇盜圖的基本手段。圖片水印 (Logo、簽名) 相較文字水印,視覺效果更佳、難以移除、可攜帶品牌識別元素。

核心函數:imagecopy()

bool imagecopy(
    resource $dst_im,   // 目標圖片 (背景圖)
    resource $src_im,   // 來源圖片 (水印圖)
    int $dst_x,         // 目標貼上位置 X
    int $dst_y,         // 目標貼上位置 Y
    int $src_x,         // 來源裁剪起始 X (通常 0)
    int $src_y,         // 來源裁剪起始 Y (通常 0)
    int $src_w,         // 來源裁剪寬度 (水印寬度)
    int $src_h          // 來源裁剪高度 (水印高度)
)

將水印完整複製至背景圖指定座標。注意:imagecopy() 不支援透明度混合,水印圖需為 GIF/PNG 並保留 Alpha 通道,或預先處理透明色。

基本水印函數實作 (隨機位置)

<?php
/**
 * 為 JPEG 背景圖添加 GIF/PNG 水印 (隨機位置)
 *
 * @param string $backgroundPath 背景圖路徑 (JPEG)
 * @param string $watermarkPath  水印圖路徑 (GIF/PNG)
 * @param int    $quality        輸出品質 0-100
 * @return bool
 */
function addWatermarkRandom(string $backgroundPath, string $watermarkPath, int $quality = 90): bool
{
    // 1. 取得尺寸
    [$bgW, $bgH] = getimagesize($backgroundPath);
    [$wmW, $wmH] = getimagesize($watermarkPath);

    if (!$bgW || !$wmW) {
        return false;
    }

    // 2. 計算隨機位置 (確保水印完整在圖內)
    $maxX = max(0, $bgW - $wmW);
    $maxY = max(0, $bgH - $wmH);
    $dstX = random_int(0, $maxX);
    $dstY = random_int(0, $maxY);

    // 3. 載入圖片資源
    $bgImage = imagecreatefromjpeg($backgroundPath);
    $wmImage = $wmH === $wmH // 簡易判斷,實際應用用 mime
        ? imagecreatefrompng($watermarkPath)
        : imagecreatefromgif($watermarkPath);

    if (!$bgImage || !$wmImage) {
        return false;
    }

    // 4. 執行複製 (水印需為真彩色且保留 Alpha)
    imagecopy($bgImage, $wmImage, $dstX, $dstY, 0, 0, $wmW, $wmH);

    // 5. 輸出
    $result = imagejpeg($bgImage, $backgroundPath, $quality);

    // 6. 釋放
    imagedestroy($bgImage);
    imagedestroy($wmImage);

    return $result;
}

// 使用範例
addWatermarkRandom('photo.jpg', 'logo.png');
?>

進階:支援透明度混合的水印 (imagecopymerge / imagecopymerge_alpha)

imagecopy() 直接複製像素,無法調整水印不透明度。若需半透明水印,需使用 imagecopymerge() 或自訂 Alpha 混合函數。

使用 imagecopymerge (簡單但品質一般)

// $pct: 0-100 不透明度
imagecopymerge($bgImage, $wmImage, $dstX, $dstY, 0, 0, $wmW, $wmH, 50); // 50% 不透明

自訂 Alpha 混合 (品質最佳,支援 PNG 逐像素 Alpha)

<?php
/**
 * 支援 Alpha 通道的水印合併
 */
function imagecopymergeAlpha(
    resource $dst_im,
    resource $src_im,
    int $dst_x,
    int $dst_y,
    int $src_x,
    int $src_y,
    int $src_w,
    int $src_h,
    int $pct = 100
): bool {
    // 建立臨時真彩色圖片
    $cut = imagecreatetruecolor($src_w, $src_h);

    // 複製背景對應區域到臨時圖
    imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);

    // 將水印複製到臨時圖 (此時會混合 Alpha)
    imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);

    // 根據不透明度混合
    imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);

    imagedestroy($cut);
    return true;
}

// 使用:50% 不透明度
imagecopymergeAlpha($bgImage, $wmImage, $dstX, $dstY, 0, 0, $wmW, $wmH, 50);
?>

九宮格定位策略 (替代隨機位置)

實際專案常需固定位置:左上、上中、右上、左中、置中、右中、左下、下中、右下。

<?php
function calculateWatermarkPosition(
    int $bgW, int $bgH,
    int $wmW, int $wmH,
    string $position = 'center',
    int $margin = 10
): array {
    $positions = [
        'top-left'     => [$margin, $margin],
        'top-center'   => [($bgW - $wmW) / 2, $margin],
        'top-right'    => [$bgW - $wmW - $margin, $margin],
        'center-left'  => [$margin, ($bgH - $wmH) / 2],
        'center'       => [($bgW - $wmW) / 2, ($bgH - $wmH) / 2],
        'center-right' => [$bgW - $wmW - $margin, ($bgH - $wmH) / 2],
        'bottom-left'  => [$margin, $bgH - $wmH - $margin],
        'bottom-center'=> [($bgW - $wmW) / 2, $bgH - $wmH - $margin],
        'bottom-right' => [$bgW - $wmW - $margin, $bgH - $wmH - $margin],
    ];

    $pos = $positions[$position] ?? $positions['center'];
    return [max(0, (int)$pos[0]), max(0, (int)$pos[1])];
}
?>

文字水印替代方案

若無 Logo 圖片,可用 imagettftext() 繪製文字水印:

$font = __DIR__ . '/fonts/NotoSansTC-Regular.otf';
$color = imagecolorallocatealpha($bgImage, 255, 255, 255, 50); // 白色 80% 不透明
imagettftext($bgImage, 24, 0, $x, $y, $color, $font, '© MyBrand');

效能與架構建議

  • 非同步處理:上傳後回應 202,背景任務 (Queue Worker) 處理水印、縮圖、上傳 CDN。
  • 原圖保留:水印版另存為新檔 (如 photo_wm.jpg),保留無水印原圖供授權下載。
  • 批次處理:大量圖片加水印時,預先載入水印資源避免重複 I/O。
  • 雲端替代:考慮使用 Cloudinary、Imgix、AWS Lambda@Edge 等服務卸載圖片處理運算。

總結

imagecopy() 是添加圖片水印的基礎函數,配合 imagecopymergeAlpha() 可實現高品質半透明疊加。生產環境建考慮:九宮格定位、非同步處理、原圖保留、雲端服務替代,構建完整的圖片版權保護體系。

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