為項目圖片添加版權保護水印是常見需求。本文提供一個開箱即用的 image_fu 類,支援 JPEG/PNG/GIF 格式,自動計算文字尺寸並定位到右下角,顏色隨機生成,適合快速集成到現有系統中。
class image_fu {
private $image; // 圖片路徑
private $img_info; // getimagesize 信息
private $img_width; // 寬度
private $img_height; // 高度
private $img_im; // GD 資源句柄
private $img_text; // 水印文字
private $img_ttf = ''; // 字體文件路徑
private $img_new; // 繪製結果
private $img_text_size; // 字體大小
private $img_jd; // 旋轉角度
/**
* 入口方法
* @param string $img 圖片路徑
* @param string $txt 水印文字
* @param string $ttf 字體文件路徑
* @param int $size 字體大小,預設 12
* @param int $jiaodu 旋轉角度,預設 0
*/
public function img($img = '', $txt = '', $ttf = '', $size = 12, $jiaodu = 0) {
// 1. 驗證圖片存在
if (!isset($img) || !file_exists($img)) {
exit('圖片文件: ' . $img . ' 不存在');
}
$this->image = $img;
$this->img_text = $txt;
$this->img_text_size = $size;
$this->img_jd = $jiaodu;
// 2. 驗證字體文件
if (file_exists($ttf)) {
$this->img_ttf = $ttf;
} else {
exit('字體文件:' . $ttf . ' 不存在!');
}
$this->imgyesno();
}
/** 檢測圖片類型並創建 GD 資源 */
private function imgyesno() {
$this->img_info = getimagesize($this->image);
$this->img_width = $this->img_info[0];
$this->img_height = $this->img_info[1];
switch ($this->img_info[2]) {
case IMAGETYPE_GIF: $this->img_im = imagecreatefromgif($this->image); break;
case IMAGETYPE_JPEG: $this->img_im = imagecreatefromjpeg($this->image); break;
case IMAGETYPE_PNG: $this->img_im = imagecreatefrompng($this->image); break;
default: exit('圖片格式不支持水印');
}
$this->img_text();
}
/** 核心繪製邏輯 */
private function img_text() {
// 開啟混色模式
imagealphablending($this->img_im, true);
// 隨機顏色
$color = imagecolorallocate($this->img_im, rand(0, 255), rand(0, 255), rand(0, 255));
// 計算文字邊界框
$box = imagettfbbox($this->img_text_size, $this->img_jd, $this->img_ttf, $this->img_text);
$w = $box[2] - $box[6]; // 文字寬度
$h = $box[3] - $box[7]; // 文字高度
// 右下角座標(留 1px 邊距)
$txt_x = $this->img_width - $w - 1;
$txt_y = $this->img_height - $h - 1;
// 繪製文字
$this->img_new = @imagettftext(
$this->img_im,
$this->img_text_size,
$this->img_jd,
$txt_x, $txt_y,
$color,
$this->img_ttf,
$this->img_text
);
// 覆蓋保存原文件
@unlink($this->image);
switch ($this->img_info[2]) {
case IMAGETYPE_GIF: imagegif($this->img_im, $this->image); break;
case IMAGETYPE_JPEG: imagejpeg($this->img_im, $this->image); break;
case IMAGETYPE_PNG: imagepng($this->img_im, $this->image); break;
default: exit('水印圖片失敗');
}
}
/** 輸出預覽標籤 */
public function img_show() {
echo '<img src="' . $this->image . '" border="0" alt="' . $this->img_text . '" />';
}
/** 析構釋放資源 */
public function __destruct() {
if (isset($this->img_im)) imagedestroy($this->img_im);
unset($this->img_info);
}
}
// 1. 引入類文件
include_once 'imageClass.php';
// 2. 實例化
$watermark = new image_fu();
// 3. 添加水印
// 參數:圖片路徑、水印文字、字體路徑、字體大小、角度
$watermark->img('photo.jpg', '© MySite 2024', 'fonts/msyh.ttf', 24, 0);
// 4. 可選:網頁預覽
$watermark->img_show();
| 技術點 | 說明 |
|---|---|
imagettfbbox() | 獲取文字邊界框座標陣列,索引 2/6 為右上/左下 X 座標,3/7 為 Y 座標 |
imagealphablending(true) | 啟用 Alpha 混色,確保水印與背景自然融合 |
常量 IMAGETYPE_* | 替代魔術數字 1/2/3,代碼可讀性更強 |
@unlink() 後重寫 | 原地覆蓋模式,簡化文件管理;生產環境建議改為輸出到新路徑保留原圖 |
imagecolorallocatealpha() 實現半透明水印imagecopy() 實現 Logo 疊加exit() 改為拋出異常,便於上層捕獲這個類雖然精簡,但涵蓋了 GD 庫處理圖片水印的核心流程:格式識別 → 資源創建 → 文字渲染 → 格式化輸出。理解這套邏輯後,你可以輕鬆擴展出功能更豐富的水印組件,或遷移到 Intervention Image 等現代庫中實現同樣效果。