利用 PHP GD2 擴展實現高性能圖片縮略圖生成,支援等比縮放、裁剪模式、多格式(JPG/PNG/GIF)輸出。本文提供生產級可用類代碼與詳細參數說明。
gd 擴展(php.ini 中 extension=gd)。imagecreatetruecolor() 真彩色畫布。<?php
// 參數:源圖路徑、目標寬、目標高、是否裁剪(1/0)、輸出路徑
$resize = new ResizeImage("upload/photo.jpg", 300, 200, 1, "thumb/photo_300x200.jpg");
// 單行完成:讀取 → 計算比例 → 縮放/裁剪 → 輸出
?>
<?php
class ResizeImage {
private $srcPath, $dstPath, $targetW, $targetH, $cut, $type, $imgRes;
public function __construct($src, $w, $h, $cut, $dst) {
$this->srcPath = $src;
$this->targetW = $w;
$this->targetH = $h;
$this->cut = (bool)$cut;
$this->dstPath = $dst;
$this->type = strtolower(pathinfo($src, PATHINFO_EXTENSION));
$this->initImage();
$this->process();
}
private function initImage() {
switch ($this->type) {
case 'jpg': case 'jpeg': $this->imgRes = imagecreatefromjpeg($this->srcPath); break;
case 'png': $this->imgRes = imagecreatefrompng($this->srcPath); break;
case 'gif': $this->imgRes = imagecreatefromgif($this->srcPath); break;
default: throw new Exception("Unsupported format: {$this->type}");
}
}
private function process() {
$srcW = imagesx($this->imgRes);
$srcH = imagesy($this->imgRes);
$srcRatio = $srcW / $srcH;
$dstRatio = $this->targetW / $this->targetH;
if ($this->cut) {
// 裁剪模式:填滿目標區域,超出部分切除
$canvas = imagecreatetruecolor($this->targetW, $this->targetH);
if ($srcRatio >= $dstRatio) {
// 寬度較寬,以高度為基準縮放,左右裁剪
$newW = $srcH * $dstRatio;
$srcX = ($srcW - $newW) / 2;
imagecopyresampled($canvas, $this->imgRes, 0, 0, $srcX, 0, $this->targetW, $this->targetH, $newW, $srcH);
} else {
// 高度較高,以寬度為基準縮放,上下裁剪
$newH = $srcW / $dstRatio;
$srcY = ($srcH - $newH) / 2;
imagecopyresampled($canvas, $this->imgRes, 0, 0, 0, $srcY, $this->targetW, $this->targetH, $srcW, $newH);
}
} else {
// 等比縮放模式:完整顯示,留白或自動調整畫布尺寸
if ($srcRatio >= $dstRatio) {
$newW = $this->targetW;
$newH = $this->targetW / $srcRatio;
} else {
$newH = $this->targetH;
$newW = $this->targetH * $srcRatio;
}
$canvas = imagecreatetruecolor($newW, $newH);
imagecopyresampled($canvas, $this->imgRes, 0, 0, 0, 0, $newW, $newH, $srcW, $srcH);
}
$this->output($canvas);
imagedestroy($canvas);
}
private function output($resource) {
switch ($this->type) {
case 'jpg': case 'jpeg': imagejpeg($resource, $this->dstPath, 90); break;
case 'png': imagepng($resource, $this->dstPath, 6); break;
case 'gif': imagegif($resource, $this->dstPath); break;
}
imagedestroy($this->imgRes);
}
}
?>
| 技術點 | 說明 |
|---|---|
| imagecreatetruecolor | 建立真彩色畫布,避免調色板模式色彩失真 |
| imagecopyresampled | 雙線性插值重採樣,品質遠優於 imagecopyresized |
| 裁剪邏輯 | 計算源圖與目標長寬比,決定以寬或高為基準,居中裁剪 |
| 輸出品質參數 | JPEG 90% 平衡體積/品質;PNG 壓縮等級 6(0-9) |
imagefill + imagesavealpha 支援 PNG/GIF 透明背景保留。Exif 讀取自動修正手機拍攝照片旋轉方向。