在內容管理系統、電商商品圖或會員頭像審核流程中,伺服器端自動為上傳圖片加上品牌 Logo 或版權文字,是保護數位資產的基本手段。本文提供一個輕量級的 editimage 類別,示範如何以 GD 函式庫實作文字浮水印與圖片浮水印,並支援自訂字體、座標與輸出模式。
class editimage {
private $imagefile; // 目標圖片路徑
private $smallimg; // 浮水印圖片路徑
private $string; // 浮水印文字
private $position; // 儲存位置
private $dst_x = 600; // 圖片浮水印 X 座標
private $dst_y = 0; // 圖片浮水印 Y 座標
private $str_x = 450; // 文字浮水印 X 座標
private $str_y = 200; // 文字浮水印 Y 座標
private $font = "c:/windows/fonts/simhei.ttf"; // 字體路徑
private $imgej; // 圖片資源控制代碼
// ... __get/__set 魔術方法
}
function __construct($imagefile, $smallimg='', $string='') {
$this->imagefile = $imagefile;
$this->smallimg = $smallimg;
$this->string = $string;
$this->imgej = $this->imagecreatef($this->imagefile);
}
建構子接受必填的目標圖片,以及選填的浮水印圖片與文字,並立即呼叫 imagecreatef() 建立 GD 資源。
function get_extname($file) {
if (file_exists($this->imagefile)) {
$img = getimagesize($file);
switch ($img[2]) {
case "1": return "gif";
case "2": return "jpg";
case "3": return "png";
}
}
return false;
}
此方法回傳副檔名字串,供後續 imagecreatefromgif/jpeg/png 選擇正確的建立函式。
原始碼僅提供到 get_extname(),核心的 wprint_img()(圖片浮水印)與 wprint_string()(文字浮水印)方法未完整呈現。以下為補完參考實作:
wprint_string()public function wprint_string() {
if (empty($this->string)) return false;
$color = imagecolorallocate($this->imgej, 255, 255, 255); // 白色
// 若需中文,請確認 $this->font 指向含中文字型的 TTF
imagettftext($this->imgej, 20, 0, $this->str_x, $this->str_y,
$color, $this->font, $this->string);
return $this;
}
wprint_img()public function wprint_img() {
if (empty($this->smallimg) || !file_exists($this->smallimg)) return false;
$logoInfo = getimagesize($this->smallimg);
switch ($logoInfo[2]) {
case 1: $logo = imagecreatefromgif($this->smallimg); break;
case 2: $logo = imagecreatefromjpeg($this->smallimg); break;
case 3: $logo = imagecreatefrompng($this->smallimg); break;
default: return false;
}
// 支援透明度疊加
imagecopy($this->imgej, $logo,
$this->dst_x, $this->dst_y, 0, 0,
$logoInfo[0], $logoInfo[1]);
imagedestroy($logo);
return $this;
}
public function output($savePath = '') {
header('Content-Type: image/png'); // 統一輸出 PNG 保留透明度
if ($savePath) {
imagepng($this->imgej, $savePath);
} else {
imagepng($this->imgej);
}
imagedestroy($this->imgej);
}
require_once 'editimage.php';
$image = new editimage(
'uploads/photo.jpg', // 目標圖片
'assets/watermark.png', // 浮水印圖片 (可為空)
'© 2024 MySite.com' // 浮水印文字 (可為空)
);
// 依需求啟用
$image->wprint_img(); // 疊加圖片浮水印
$image->wprint_string(); // 疊加文字浮水印
// 直接輸出瀏覽器或存檔
$image->output('output/photo_watermarked.png');
imagesx/y 計算置中、右下、左上等九個錨點,取代固定座標。imagecopymerge($dst, $src, $dx, $dy, $sx, $sy, $sw, $sh, $pct),$pct 0~100 控制不透明度。imagettfbbox 計算寬度,超出畫布寬度時自動換行。DirectoryIterator 遍歷資料夾,配合 exec('mogrify ...') 或佇列系統分散負載。editimage 類別展示了 GD 浮水印的基本骨架,雖原始碼不完整,但結構清晰,極易擴充。實務上建議直接採用 Intervention Image 的 insert() 方法,單行即可完成相同功能並支援更多進階選項。