在用戶上傳頭像、生成海報、版權保護等場景中,往往需要在圖片上動態繪製文字水印。PHP GD 擴展提供了完整的圖像處理能力,本文封裝一個 makethumb() 函數,支持多圖片格式、自動換行、顏色/字體大小自定義。
<?php
/**
* 在圖片上繪製文字水印並直接輸出 JPEG
*
* @param string $srcFile 源圖片路徑(支持 GIF/JPG/PNG)
* @param string $text 水印文字,空則使用預設
* @param int $size 字體大小(像素),預設 12
* @param int $R 紅色分量 0-255
* @param int $G 綠色分量 0-255
* @param int $B 藍色分量 0-255
*/
function makethumb(string $srcFile, string $text = '', int $size = 12, int $R = 0, int $G = 0, int $B = 0): void
{
// 預設值處理
if ($text === '') {
$text = 'welcome xs.net.ru xayle';
$size = 20;
$R = 255;
}
if ($size < 1) $size = 12;
// 1. 根據 MIME 類型創建圖像資源
[$width, $height, $type] = getimagesize($srcFile);
$createFrom = match ($type) {
IMAGETYPE_GIF => 'imagecreatefromgif',
IMAGETYPE_JPEG => 'imagecreatefromjpeg',
IMAGETYPE_PNG => 'imagecreatefrompng',
default => throw new Exception('Unsupported image type'),
};
$im = $createFrom($srcFile) ?: throw new Exception('Failed to load image');
// 2. 創建真彩色畫布並複製原圖(保持原尺寸)
$canvas = imagecreatetruecolor($width, $height);
imagecopyresampled($canvas, $im, 0, 0, 0, 0, $width, $height, $width, $height);
imagedestroy($im); // 釋放原資源
// 3. 分配文字顏色
$color = imagecolorallocate($canvas, $R, $G, $B);
// 4. 字體文件(需確保 2.ttf 存在於腳本目錄)
$font = __DIR__ . '/2.ttf';
if (!is_file($font)) throw new Exception('Font file not found: ' . $font);
// 5. 自動換行繪製邏輯
$lineHeight = ceil($size * 16 / 12); // 經驗行高
$charsPerLine = ceil(12 * 22 / $size); // 經驗每行字符數
$len = mb_strlen($text, 'UTF-8');
for ($i = 0, $y = $lineHeight; $i < $len; $i += $charsPerLine, $y += $lineHeight) {
$line = mb_substr($text, $i, $charsPerLine, 'UTF-8');
// 座標 (8, $y) 為左邊距 8px,基線位置
imagettftext($canvas, $size, 0, 8, $y, $color, $font, $line);
}
// 6. 輸出 JPEG 並清理
header('Content-Type: image/jpeg');
imagejpeg($canvas);
imagedestroy($canvas);
}
// === 使用示例 ===
// makethumb('face.jpg', '版權所有 © 2024', 14, 255, 255, 255); // 白色水印
?>
| 環節 | 說明 |
|---|---|
| 格式自適應 | 使用 getimagesize() 返回的 $type 常量(IMAGETYPE_*)判斷格式,避免擴展名不可靠 |
| 真彩色畫布 | imagecreatetruecolor() 支持 24 位色,配合 imagecopyresampled() 高質量縮放/複製 |
| 字體依賴 | 需服務器安裝 FreeType,PHP 編譯時加入 --with-freetype;字體文件 2.ttf 需可讀 |
| 中文換行 | 採用 mb_substr() 按字符數截取,配合經驗公式估算行寬/高,簡易可用;生產環境建議用 imagettfbbox() 精確測量 |
| 內存管理 | 及時 imagedestroy() 釋放 GD 資源,防止高併發下內存洩漏 |
imagecolorallocatealpha() 實現半透明水印$position(左上/右下/中心/平鋪),根據 imagettfbbox() 計算座標imagettftext() 第 3 參數即旋轉角度,可實現斜向水印$outputType 參數,支持 imagepng()、imagewebp() 等ext-gd、ext-mbstring__DIR__ . '/font.ttf',避免工作目錄變更導致找不到header() 前不能有任何輸出(含 BOM、空白行),否則圖片損壞memory_limit 或分塊處理本函數提供了一個開箱即用的文字水印方案,適合中小項目快速集成。對於高性能、複雜排版需求,建議引入 Intervention Image 等現代化庫,底層同樣基於 GD/Imagick,但 API 更優雅、功能更豐富。