功能特性
- 支援 JPEG / PNG / GIF 三種格式讀寫
- 自動計算縮放比例,**保持原圖長寬比**
- 優先使用 `imagecreatetruecolor()` + `imagecopyresampled()`(高畫質),退回 `imagecreate()` + `imagecopyresized()`(舊版 GD 相容)
- 目標尺寸大於原圖時**不放大**,置中輸出
- 輸出格式跟隨來源,或統一輸出 JPEG
完整函式代碼
<?php
/**
* 通用縮圖函式
*
* @param string $srcFile 來源圖檔路徑
* @param int $toW 目標寬度
* @param int $toH 目標高度
* @param string $toFile 輸出路徑(空則覆蓋來源)
* @return bool
*/
function ImageResize(string $srcFile, int $toW, int $toH, string $toFile = ''): bool
{
if ($toFile === '') $toFile = $srcFile;
if (!file_exists($srcFile)) {
trigger_error("來源檔案不存在:$srcFile", E_USER_WARNING);
return false;
}
$info = getimagesize($srcFile);
if (!$info) {
trigger_error("無法讀取圖片資訊:$srcFile", E_USER_WARNING);
return false;
}
$mime = $info['mime'];
switch ($mime) {
case 'image/gif':
if (!function_exists('imagecreatefromgif')) return _gdNotSupport('GIF');
$im = imagecreatefromgif($srcFile);
break;
case 'image/jpeg':
if (!function_exists('imagecreatefromjpeg')) return _gdNotSupport('JPEG');
$im = imagecreatefromjpeg($srcFile);
break;
case 'image/png':
if (!function_exists('imagecreatefrompng')) return _gdNotSupport('PNG');
$im = imagecreatefrompng($srcFile);
break;
default:
trigger_error("不支援的圖片格式:$mime", E_USER_WARNING);
return false;
}
$srcW = imagesx($im);
$srcH = imagesy($im);
// 計算縮放後尺寸(保持比例)
$scale = min($toW / $srcW, $toH / $srcH);
if ($scale >= 1) {
// 原圖較小,不放大,置中畫布
$dstW = $srcW;
$dstH = $srcH;
} else {
$dstW = (int)round($srcW * $scale);
$dstH = (int)round($srcH * $scale);
}
// 建立目標畫布
if (function_exists('imagecreatetruecolor')) {
$dst = imagecreatetruecolor($dstW, $dstH);
// PNG/GIF 透明度處理
if ($mime === 'image/png' || $mime === 'image/gif') {
imagealphablending($dst, false);
imagesavealpha($dst, true);
$transparent = imagecolorallocatealpha($dst, 255, 255, 255, 127);
imagefilledrectangle($dst, 0, 0, $dstW, $dstH, $transparent);
}
imagecopyresampled($dst, $im, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH);
} else {
$dst = imagecreate($dstW, $dstH);
imagecopyresized($dst, $im, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH);
}
// 輸出
$success = false;
switch ($mime) {
case 'image/jpeg':
$success = imagejpeg($dst, $toFile, 90);
break;
case 'image/png':
$success = imagepng($dst, $toFile, 6);
break;
case 'image/gif':
$success = imagegif($dst, $toFile);
break;
}
imagedestroy($im);
imagedestroy($dst);
return $success;
}
function _gdNotSupport(string $format): bool
{
trigger_error("GD 庫未編譯 $format 支援", E_USER_WARNING);
return false;
}
使用範例
// 產生 300x300 內的縮圖,保持比例
ImageResize('uploads/photo.jpg', 300, 300, 'uploads/thumb_photo.jpg');
// 批次處理
foreach (glob('uploads/*.{jpg,png,gif}', GLOB_BRACE) as $file) {
ImageResize($file, 800, 600, 'thumbs/' . basename($file));
}
進階建議
- 大量圖片處理建議用 **ImageMagick (imagick extension)**,效能更好、格式支援更全。
- Web 即時縮圖可考慮 **Nginx ngx_http_image_filter_module** 或 **Thumbor** 等專用服務。
- 輸出 WebP 格式可大幅減小體積:`imagewebp($dst, $toFile, 80)`(PHP 5.5+)。