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

PHP 圖片加水印:GD 庫實現右下角疊加透明 PNG

     編輯:PHP 綜合知識

核心函數

<?php
/**
 * 給 JPEG 圖片加 PNG 水印 (右下角)
 * @param string $target      源圖路徑 (JPG)
 * @param string $wtrmrk_file 水印圖路徑 (PNG,帶透明通道)
 * @param string $newcopy     輸出路徑
 * @return bool
 */
function watermark_image(string $target, string $wtrmrk_file, string $newcopy): bool
{
    // 1. 載入水印 (保留 Alpha)
    $watermark = imagecreatefrompng($wtrmrk_file);
    imagealphablending($watermark, false);
    imagesavealpha($watermark, true);
    
    // 2. 載入目標圖
    $img = imagecreatefromjpeg($target);
    if (!$img || !$watermark) return false;
    
    // 3. 計算座標 (右下角,留 10px 邊距)
    $img_w = imagesx($img);
    $img_h = imagesy($img);
    $w_w = imagesx($watermark);
    $w_h = imagesy($watermark);
    $dst_x = $img_w - $w_w - 10;
    $dst_y = $img_h - $w_h - 10;
    
    // 4. 疊加
    imagecopy($img, $watermark, $dst_x, $dst_y, 0, 0, $w_w, $w_h);
    
    // 5. 輸出
    $ok = imagejpeg($img, $newcopy, 90); // 品質 90
    
    // 6. 釋放資源
    imagedestroy($img);
    imagedestroy($watermark);
    
    return $ok;
}

// 使用
watermark_image('photo.jpg', 'logo.png', 'photo_wm.jpg');
?>

進階:支援多格式、多位置、文字水印

<?php
class Watermarker
{
    public function __construct(
        public int $margin = 10,
        public int $quality = 85,
        public int $position = 9 // 1-9 九宮格,9=右下
    ) {}
    
    public function add(string $src, string $water, string $dst): bool
    {
        $srcInfo = getimagesize($src);
        $waterInfo = getimagesize($water);
        if (!$srcInfo || !$waterInfo) return false;
        
        $createSrc = match ($srcInfo[2]) {
            IMAGETYPE_JPEG => 'imagecreatefromjpeg',
            IMAGETYPE_PNG  => 'imagecreatefrompng',
            IMAGETYPE_GIF  => 'imagecreatefromgif',
            default => null,
        };
        $createWater = match ($waterInfo[2]) {
            IMAGETYPE_PNG => 'imagecreatefrompng', // 水印建議 PNG
            default => null,
        };
        if (!$createSrc || !$createWater) return false;
        
        $img = $createSrc($src);
        $wm = $createWater($water);
        imagealphablending($wm, false);
        imagesavealpha($wm, true);
        
        [$sx, $sy] = [$srcInfo[0], $srcInfo[1]];
        [$wx, $wy] = [$waterInfo[0], $waterInfo[1]];
        
        // 九宮格座標
        $positions = [
            1 => [$this->margin, $this->margin],
            2 => [($sx-$wx)/2, $this->margin],
            3 => [$sx-$wx-$this->margin, $this->margin],
            4 => [$this->margin, ($sy-$wy)/2],
            5 => [($sx-$wx)/2, ($sy-$wy)/2],
            6 => [$sx-$wx-$this->margin, ($sy-$wy)/2],
            7 => [$this->margin, $sy-$wy-$this->margin],
            8 => [($sx-$wx)/2, $sy-$wy-$this->margin],
            9 => [$sx-$wx-$this->margin, $sy-$wy-$this->margin],
        ];
        [$dx, $dy] = $positions[$this->position] ?? $positions[9];
        
        imagecopy($img, $wm, $dx, $dy, 0, 0, $wx, $wy);
        
        $save = match ($srcInfo[2]) {
            IMAGETYPE_JPEG => imagejpeg($img, $dst, $this->quality),
            IMAGETYPE_PNG  => imagepng($img, $dst, 9),
            IMAGETYPE_GIF  => imagegif($img, $dst),
            default => false,
        };
        
        imagedestroy($img);
        imagedestroy($wm);
        return $save;
    }
    
    /** 文字水印 */
    public function addText(string $src, string $text, string $dst, int $fontSize = 20, string $color = 'FFFFFF', int $alpha = 50): bool
    {
        // ... 類似邏輯,使用 imagettftext ...
    }
}

// 用法
$wm = new Watermarker(margin: 20, position: 9);
$wm->add('photo.jpg', 'logo.png', 'out.jpg');
?>

常見問題

問題解決
水印背景變黑必須 imagealphablending($wm, false); imagesavealpha($wm, true);
輸出圖變模糊JPEG 品質參數調高 (80-95),或輸出 PNG
記憶體溢出大圖先 imagescale 縮小再加水印,或用 Imagick 流式處理
透明 PNG 輸出背景黑目標圖若為 PNG,同樣需開啟 alphablending/savealpha

效能建議

  • 高併發場景改用 Imagick (C 底層,多線程、流式、記憶體友好)
  • CDN 邊緣節點加水印 (如 Cloudflare Workers、阿里雲 CDN 圖片處理參數)
  • 預生成多種尺寸水印圖,避免運行時縮放
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved