在 PHP 中為圖片加上文字水印是常見需求。本文將同一功能分別以「物件導向(OOP)」與「程序式」兩種風格實作,並對比兩者優缺點,幫助你根據專案規模與團隊習慣選擇合適風格。
程式碼由上而下依序執行:載入圖片 → 分配顏色 → 寫入文字 → 輸出 → 銷毀資源。無需實例化類別,適合一次性腳本或初學者練習。
// 指定圖片路徑
$src = '001.png';
// 取得圖片資訊與副檔名
$info = getimagesize($src);
$type = image_type_to_extension($info[2], false);
// 動態呼叫 imagecreatefromjpeg/png/gif 等函式
$fun = "imagecreatefrom{$type}";
$image = $fun($src);
// 設定半透明白色文字色
$col = imagecolorallocatealpha($image, 255, 255, 255, 50);
$content = 'helloworld';
// 寫入文字(字體大小 5,座標 20,30)
imagestring($image, 5, 20, 30, $content, $col);
// 輸出圖片
header('Content-type: ' . $info['mime']);
$func = "image{$type}";
$func($image);
// 釋放記憶體
imagedestroy($image);
將圖片資源、資訊封裝於 Image_class 類別中。建構子負責載入圖片,fontMark() 提供參數化水印設定,show() 輸出,解構子自動釋放資源。外部呼叫只需 new Image_class() → fontMark() → show() 三步驟,介面清晰。
class Image_class {
private $image;
private $info;
public function __construct($src) {
$info = getimagesize($src);
$type = image_type_to_extension($info[2], false);
$this->info = $info;
$this->info['type'] = $type;
$fun = "imagecreatefrom{$type}";
$this->image = $fun($src);
}
public function fontMark($fontsize, $x, $y, $color, $text) {
$col = imagecolorallocatealpha($this->image, $color[0], $color[1], $color[2], $color[3]);
imagestring($this->image, $fontsize, $x, $y, $text, $col);
}
public function show() {
header('content-type: ' . $this->info['mime']);
$fun = 'image' . $this->info['type'];
$fun($this->image);
}
public function __destruct() {
imagedestroy($this->image);
}
}
// 使用範例
$obj = new Image_class('001.png');
$obj->fontMark(20, 20, 30, [255, 255, 255, 60], 'hello');
$obj->show();
| 維度 | 程序式 | 物件導向 |
|---|---|---|
| 學習曲線 | 低,適合入門 | 需理解類別、封裝、建構子/解構子 |
| 程式碼復用 | 靠函式切割,較難管理狀態 | 天然支援繼承、多型,易建立水印庫 |
| 資源管理 | 手動呼叫 imagedestroy() | 解構子自動釋放,減少記憶體洩漏 |
| 擴充性 | 新增功能需修改主流程 | 可繼承擴充(如加入圖片水印、旋轉等) |
| 適用場景 | 一次性腳本、簡單專案、教學示範 | 框架開發、長期維護專案、團隊協作 |
imagettftext() 並載入 .ttf 字體檔。ini_set('memory_limit', '256M'))。WatermarkInterface,支援策略模式切換文字/圖片水印。兩種寫法各有優劣,沒有絕對優劣。初學者可先從程序式掌握 GD 基礎操作,隨著專案增長再重構為物件導向,享受封裝帶來的維護便利性。完整程式碼已附上,歡迎直接套用至專案中。