功能特色
- 相容
imagecreatefromjpeg/png/gif 自動偵測格式
- 九大預設位置(左上、中上、右上、置中、左下、中下、右下、左中、右中)+ 自訂座標
- 透明度 0~100 可調(
imagecopymerge)
- 輸出保持原圖格式,錯誤代碼細分(-1~-5)
核心函式
<?php
/**
* 圖片加浮水印
* @param string $srcImg 原圖路徑
* @param string $waterImg 浮水印圖路徑
* @param string $savepath 儲存目錄(預設同原圖)
* @param string $savename 儲存檔名(預設同原圖)
* @param int $position 1~9 九宮格,預設 5 右下
* @param int $alpha 透明度 0~100,預設 30
* @return string|int 成功回傳新檔路徑,失敗回傳負數錯誤碼
*/
function img_water_mark($srcImg, $waterImg, $savepath = null, $savename = null, $position = 5, $alpha = 30) {
$info = pathinfo($srcImg);
$savepath = $savepath ?: $info['dirname'];
$savename = $savename ?: $info['basename'];
$savefile = $savepath . '/' . $savename;
$srcInfo = @getimagesize($srcImg);
if (!$srcInfo) return -1; // 原檔不存在或非圖片
$waterInfo = @getimagesize($waterImg);
if (!$waterInfo) return -2; // 浮水印不存在
$srcObj = image_create_from_ext($srcImg);
if (!$srcObj) return -3;
$waterObj = image_create_from_ext($waterImg);
if (!$waterObj) return -4;
// 九宮格座標計算
$w = $srcInfo[0]; $h = $srcInfo[1];
$ww = $waterInfo[0]; $wh = $waterInfo[1];
switch ($position) {
case 1: $x = 0; $y = 0; break; // 左上
case 2: $x = $w - $ww; $y = 0; break; // 右上
case 3: $x = ($w - $ww) / 2; $y = ($h - $wh) / 2; break; // 置中
case 4: $x = 0; $y = $h - $wh; break; // 左下
case 5: $x = $w - $ww; $y = $h - $wh; break; // 右下(預設)
case 6: $x = ($w - $ww) / 2; $y = 0; break; // 中上
case 7: $x = ($w - $ww) / 2; $y = $h - $wh; break; // 中下
case 8: $x = 0; $y = ($h - $wh) / 2; break; // 左中
case 9: $x = $w - $ww; $y = ($h - $wh) / 2; break; // 右中
default: $x = $y = 0;
}
// 合成:支援透明度
imagecopymerge($srcObj, $waterObj, $x, $y, 0, 0, $ww, $wh, $alpha);
// 依原圖類型輸出
$result = false;
switch ($srcInfo[2]) {
case IMAGETYPE_GIF: $result = imagegif($srcObj, $savefile); break;
case IMAGETYPE_JPEG: $result = imagejpeg($srcObj, $savefile, 90); break;
case IMAGETYPE_PNG: $result = imagepng($srcObj, $savefile); break;
}
if (!$result) return -5;
imagedestroy($srcObj);
imagedestroy($waterObj);
return $savefile;
}
/** 依副檔名/MIME 自動建立 GD 資源 */
function image_create_from_ext($imgfile) {
$info = getimagesize($imgfile);
switch ($info[2]) {
case IMAGETYPE_GIF: return imagecreatefromgif($imgfile);
case IMAGETYPE_JPEG: return imagecreatefromjpeg($imgfile);
case IMAGETYPE_PNG: return imagecreatefrompng($imgfile);
}
return null;
}
?>
使用範例
<?php
$src = 'photo.jpg';
$mark = 'logo.png';
$out = img_water_mark($src, $mark, null, 'watermarked.jpg', 5, 50);
if ($out > 0) {
echo "成功:
";
} else {
echo "失敗,錯誤碼:{$out}";
}
?>
進階擴充建議
- 文字浮水印:用
imagettftext() 繪製 TTF 字型,支援旋轉、陰影、描邊。
- 平鋪浮水印:雙重迴圈
imagecopymerge 鋪滿整圖,防盜圖更強。
- 大圖分塊處理:超大圖 (>5000px) 易超出記憶體,可用
imagecrop 分塊合成再拼接。
- 非同步佇列:上傳後推入 Queue,Worker 處理浮水印,避免阻塞 HTTP 請求。
常見坑點
- GD 不支援 WebP 輸出(PHP 8.1+
imagewebp 已支援,舊版需用 libwebp 指令)。
- JPG 輸出品質預設 75,建議明確指定 90~95。
- PNG 透明通道若在浮水印上方會遮蓋,注意圖層順序。