| 功能 | 方法 | 關鍵特性 |
| 水印 | watermark() | 圖片/文字水印、9 種位置、透明度、輸出覆蓋或新文件 |
| 縮略圖 | thumb() | 5 種模式(寬固定/高固定/寬固定裁高/高固定裁寬/等比)、保持透明、自定義後綴 |
核心類 Water
<?php
class Water {
// 水印配置
private $watermark_on = '1';
public $water_img; // 水印圖片路徑
public $pos = 1; // 1-9 九宮格位置
public $pct = 80; // 圖片水印透明度 0-100
public $quality = 80; // JPEG 輸出質量
public $text = '樂趣網zlblog.sinaapp.com'; // 文字水印內容
public $size = 12; // 文字大小
public $color = '#000000';
public $font = 'font.ttf';
// 縮略圖配置
private $thumb_on = 1;
public $thumb_type = 1; // 1-5 模式
public $thumb_width;
public $thumb_height;
public $thumb_fix = '_dq'; // 輸出文件後綴
// 驗證文件存在且為支持格式
private function check($img) {
$ext = strtolower(strrchr($img, '.'));
return extension_loaded('gd') && file_exists($img) && in_array($ext, ['.jpg','.jpeg','.png','.gif']);
}
// ========== 縮略圖 ==========
public function thumb($img, $outfile='', $t_type='', $t_w='', $t_h='') {
if (!$this->check($img) || !$this->thumb_on) return false;
$t_type = $t_type ?: $this->thumb_type;
$t_w = $t_w ?: $this->thumb_width;
$t_h = $t_h ?: $this->thumb_height;
$info = getimagesize($img);
$iw = $info[0]; $ih = $info[1];
$ext = image_type_to_extension($info[2]); // .jpg/.png/.gif
// 計算目標尺寸與裁切區域
$size = $this->thumb_size($iw, $ih, $t_w, $t_h, $t_type);
// 創建源圖資源
$func = "imagecreatefrom".substr($ext, 1);
$src = $func($img);
// 創建目標資源 (GIF/PNG 用調色板保持透明)
if (in_array($ext, ['.gif','.png'])) {
$dst = imagecreate($size[0], $size[1]);
$transparent = imagecolorallocate($dst, 255,0,0);
} else {
$dst = imagecreatetruecolor($size[0], $size[1]);
}
// 重採樣縮放
if (function_exists('imagecopyresampled')) {
imagecopyresampled($dst, $src, 0,0,0,0, $size[0],$size[1], $size[2],$size[3]);
} else {
imagecopyresized($dst, $src, 0,0,0,0, $size[0],$size[1], $size[2],$size[3]);
}
// 處理透明色
if (in_array($ext, ['.gif','.png'])) imagecolortransparent($dst, $transparent);
// 輸出文件
$outfile = $outfile ?: substr($img,0,strripos($img,'.')).$this->thumb_fix.$ext;
$ofunc = "image".substr($ext, 1);
$ofunc($dst, $outfile);
imagedestroy($dst); imagedestroy($src);
return $outfile;
}
// 計算縮略圖尺寸邏輯
private function thumb_size($iw,$ih,$tw,$th,$type) {
$w=$tw; $h=$th; $cw=$iw; $ch=$ih;
if ($iw<=$tw && $ih<$th) { $w=$iw; $h=$ih; }
else {
if ($type>0) {
switch($type) {
case 1: $h = $tw/$iw*$ih; break; // 寬固定,高等比
case 2: $w = $th/$ih*$iw; break; // 高固定,寬等比
case 3: $ch = $iw/$tw*$th; break; // 寬固定,高裁切
case 4: $cw = $ih/$th*$tw; break; // 高固定,寬裁切
default: // 等比縮放
if (($iw/$tw) > ($ih/$th)) $h = $tw/$iw*$th;
elseif (($iw/$tw) < ($ih/$th)) $w = $th/$ih*$tw;
else { $w=$tw; $h=$th; }
}
}
}
return [$tw, $th, $cw, $ch];
}
// ========== 水印 ==========
public function watermark($img, $pos='', $out_img='', $water_img='', $text='') {
if (!$this->check($img) || !$this->watermark_on) return false;
$water_img = $water_img ?: $this->water_img;
$wm_on = $this->check($water_img) ? 1 : 0;
$out_img = $out_img ?: $img;
$pos = $pos ?: $this->pos;
$text = $text ?: $this->text;
$info = getimagesize($img);
$iw = $info[0]; $ih = $info[1];
// 水印資源
if ($wm_on) {
$winfo = getimagesize($water_img);
$ww = $winfo[0]; $wh = $winfo[1];
if ($iw < $ww || $ih < $wh) return false;
$wfunc = "imagecreatefrom".substr(image_type_to_extension($winfo[2]),1);
$wmark = $wfunc($water_img);
} else {
if (empty($text) || strlen($this->color)!=7) return false;
$tbox = imagettfbbox($this->size, 0, $this->font, $text);
$ww = $tbox[2]-$tbox[6]; $wh = $tbox[3]-$tbox[7];
}
// 源圖資源
$sfunc = "imagecreatefrom".substr(image_type_to_extension($info[2]),1);
$src = $sfunc($img);
// 計算水印位置 (九宮格)
switch($pos) {
case 1: $x=$y=25; break;
case 2: $x=($iw-$ww)/2; $y=25; break;
case 3: $x=$iw-$ww; $y=25; break;
case 4: $x=25; $y=($ih-$wh)/2; break;
case 5: $x=($iw-$ww)/2; $y=($ih-$wh)/2; break;
case 6: $x=$iw-$ww; $y=($ih-$wh)/2; break;
case 7: $x=25; $y=$ih-$wh; break;
case 8: $x=($iw-$ww)/2; $y=$ih-$wh; break;
case 9: $x=$iw-$ww; $y=$ih-$wh; break;
default: $x=mt_rand(25,$iw-$ww); $y=mt_rand(25,$ih-$wh);
}
// 繪製水印
if ($wm_on) {
imagecopymerge($src, $wmark, $x, $y, 0,0, $ww,$wh, $this->pct);
} else {
$r=hexdec(substr($this->color,1,2));
$g=hexdec(substr($this->color,3,2));
$b=hexdec(substr($this->color,5,2));
$c = imagecolorallocate($src,$r,$g,$b);
imagettftext($src, $this->size, 0, $x, $y, $c, $this->font, $text);
}
// 輸出
$ofunc = "image".substr(image_type_to_extension($info[2]),1);
$ofunc($src, $out_img);
imagedestroy($src); if(isset($wmark)) imagedestroy($wmark);
return true;
}
}
?>
使用示例
$w = new Water();
$w->thumb_width = 300; $w->thumb_height = 200;
$w->thumb('photo.jpg'); // 生成 photo_dq.jpg
$w->water_img = 'logo.png';
$w->watermark('photo.jpg', 9, 'photo_wm.jpg'); // 右下角圖片水印
$w->watermark('photo.jpg', 5, 'photo_text.jpg', '', '版權所有'); // 居中文字水印
關鍵技術點
- 格式自適應:
image_type_to_extension + 動態函數名調用 (imagecreatefromjpeg 等)
- 透明保持:GIF/PNG 使用
imagecreate + imagecolortransparent
- 高質量縮放:優先
imagecopyresampled 雙三次插值
- 九宮格定位:1-9 對應左上到右下,含隨機模式
- 混合模式:圖片水印用
imagecopymerge 支持透明度,文字用 imagettftext
總結
Water 類將 GD 庫圖片處理封裝為水印與縮略圖兩大核心功能,支持主流格式、多種縮放策略、靈活定位與透明度控制。代碼結構模塊化,易於擴展(如添加旋轉、濾鏡、圓角等)。生產環境建議加入錯誤異常處理、文件權限檢查、臨時文件清理機制。
- 上一篇文章: PHP 面向對象實現驗證碼類:支持干擾線、噪點、TTF 字體、隨機字符
- 下一篇文章: JavaScript 動態創建樣式表與樣式規則:高效操作 CSSOM 避免 DOM 遍歷
Copyright ©
程式碼之家 All Rights Reserved