利用 PHP GD 擴充套件實作圖片等比例縮放,適用於縮圖生成、上傳預覽等場景。本文提供完整可執行腳本,支援 JPEG 格式,並說明如何擴充支援 PNG/GIF/WebP 及品質控制。
<?php
// 設定
$srcPath = __DIR__ . '/q.jpg'; // 來源圖片
$dstPath = __DIR__ . '/q1.jpg'; // 輸出圖片
$scale = 0.3; // 縮放比例 (30%)
// 1. 取得原始尺寸
list($srcW, $srcH) = getimagesize($srcPath);
if (!$srcW || !$srcH) {
die('無法讀取圖片或格式不支援');
}
// 2. 計算目標尺寸
$dstW = (int)($srcW * $scale);
$dstH = (int)($srcH * $scale);
// 3. 建立真彩色目標畫布
$dstImg = imagecreatetruecolor($dstW, $dstH);
// 4. 載入來源圖片 (JPEG)
$srcImg = imagecreatefromjpeg($srcPath);
// 5. 等比例複製並重取樣 (imagecopyresampled 品質優於 imagecopyresized)
imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH);
// 6. 輸出 JPEG (品質 85)
imagejpeg($dstImg, $dstPath, 85);
// 7. 釋放記憶體
imagedestroy($dstImg);
imagedestroy($srcImg);
echo "縮圖生成成功:{$dstPath} ({$dstW}x{$dstH})";
?>
<?php
/**
* 等比例縮放圖片 (支援 JPEG/PNG/GIF/WebP)
* @param string $srcPath 來源路徑
* @param string $dstPath 目標路徑
* @param int $maxDim 最大長邊像素 (0 表示不限制)
* @param int $quality 輸出品質 1-100 (僅 JPEG/WebP 生效)
* @return array ['width'=>, 'height'=>, 'type'=>] 或 false
*/
function smartResize($srcPath, $dstPath, $maxDim = 800, $quality = 85) {
// 1. 偵測圖片類型
$info = getimagesize($srcPath);
if (!$info) return false;
[$srcW, $srcH, $type] = $info;
// 2. 計算目標尺寸
if ($maxDim > 0) {
$ratio = min($maxDim / $srcW, $maxDim / $srcH, 1); // 不放大
$dstW = (int)($srcW * $ratio);
$dstH = (int)($srcH * $ratio);
} else {
$dstW = $srcW; $dstH = $srcH;
}
// 3. 載入來源 (依類型分派)
$createFrom = [
IMAGETYPE_JPEG => 'imagecreatefromjpeg',
IMAGETYPE_PNG => 'imagecreatefrompng',
IMAGETYPE_GIF => 'imagecreatefromgif',
IMAGETYPE_WEBP => 'imagecreatefromwebp',
];
if (!isset($createFrom[$type])) return false;
$srcImg = $createFrom[$type]($srcPath);
// 4. 建立目標畫布 (保留透明度)
$dstImg = imagecreatetruecolor($dstW, $dstH);
if ($type === IMAGETYPE_PNG || $type === IMAGETYPE_GIF || $type === IMAGETYPE_WEBP) {
imagealphablending($dstImg, false);
imagesavealpha($dstImg, true);
$transparent = imagecolorallocatealpha($dstImg, 255, 255, 255, 127);
imagefill($dstImg, 0, 0, $transparent);
}
// 5. 高品質重取樣
imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH);
// 6. 輸出 (依類型分派)
$saveAs = [
IMAGETYPE_JPEG => fn() => imagejpeg($dstImg, $dstPath, $quality),
IMAGETYPE_PNG => fn() => imagepng($dstImg, $dstPath, 9), // PNG 壓縮等級 0-9
IMAGETYPE_GIF => fn() => imagegif($dstImg, $dstPath),
IMAGETYPE_WEBP => fn() => imagewebp($dstImg, $dstPath, $quality),
];
$saveAs[$type]();
// 7. 清理
imagedestroy($srcImg);
imagedestroy($dstImg);
return ['width' => $dstW, 'height' => $dstH, 'type' => $type];
}
// 使用範例
$result = smartResize('upload/photo.jpg', 'thumb/photo.jpg', 400, 80);
if ($result) {
echo "成功:{$result['width']}x{$result['height']}";
} else {
echo "失敗:格式不支援或檔案損壞";
}
?>
| 函數 | 品質 | 速度 | 適用場景 |
|---|---|---|---|
imagecopyresized | 低 (鋸齒明顯) | 快 | 極大量批次、即時預覽 |
imagecopyresampled | 高 (雙立方插值) | 中 | 正式縮圖、使用者頭像、商品圖 |
ini_set('memory_limit', '256M') 或分塊處理 (Imagick 更適合)。imagealphablending(false) + imagesavealpha(true) 並填充透明色。--with-webp,或改用 Imagick。exif_read_data() 讀取並手動 imagerotate(),或改用 Imagick autoOrientImage()。ImageMagick (Imagick 擴充套件) 效能更好、格式支援更全、自動處理 EXIF 方向、記憶體管理更優。同等功能程式碼更簡潔:
$im = new Imagick($srcPath); $im->thumbnailImage($maxDim, $maxDim, true); // true = 等比例 $im->writeImage($dstPath);
GD 適合輕量環境、無法安裝擴充套件的虛擬主機;正式專案強烈建議使用 Imagick。