數位內容易被盜用,水印是宣示版權、阻嚇盜圖的基本手段。圖片水印 (Logo、簽名) 相較文字水印,視覺效果更佳、難以移除、可攜帶品牌識別元素。
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');
?>
imagecopy() 直接複製像素,無法調整水印不透明度。若需半透明水印,需使用 imagecopymerge() 或自訂 Alpha 混合函數。
// $pct: 0-100 不透明度
imagecopymerge($bgImage, $wmImage, $dstX, $dstY, 0, 0, $wmW, $wmH, 50); // 50% 不透明
<?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');
photo_wm.jpg),保留無水印原圖供授權下載。imagecopy() 是添加圖片水印的基礎函數,配合 imagecopymergeAlpha() 可實現高品質半透明疊加。生產環境建考慮:九宮格定位、非同步處理、原圖保留、雲端服務替代,構建完整的圖片版權保護體系。