PHP 必須編譯安裝 GD2 擴充 (--with-gd),支援 JPEG、PNG、GIF 格式。
<?php
class ResizeImage {
private $srcImg, $dstImg, $type;
private $width, $height;
private $resizeW, $resizeH, $cut;
public function __construct($src, $dstW, $dstH, $cut, $dstPath) {
$this->srcImg = $src;
$this->resizeW = $dstW;
$this->resizeH = $dstH;
$this->cut = $cut; // 1=裁切填滿, 0=等比縮放含留白
$this->type = strtolower(substr(strrchr($src, '.'), 1));
$this->initImage();
$this->dstImg = $dstPath;
$this->process();
}
private function initImage() {
switch ($this->type) {
case 'jpg': case 'jpeg': $this->im = imagecreatefromjpeg($this->srcImg); break;
case 'gif': $this->im = imagecreatefromgif($this->srcImg); break;
case 'png': $this->im = imagecreatefrompng($this->srcImg); break;
default: throw new Exception("Unsupported format: {$this->type}");
}
$this->width = imagesx($this->im);
$this->height = imagesy($this->im);
}
private function process() {
$srcRatio = $this->width / $this->height;
$dstRatio = $this->resizeW / $this->resizeH;
if ($this->cut) {
// 裁切模式:以目標比例裁切源圖再縮放
if ($srcRatio >= $dstRatio) {
// 來源較寬 → 高度優先,左右裁切
$cropH = $this->height;
$cropW = $cropH * $dstRatio;
$srcX = ($this->width - $cropW) / 2;
$srcY = 0;
} else {
// 來源較高 → 寬度優先,上下裁切
$cropW = $this->width;
$cropH = $cropW / $dstRatio;
$srcX = 0;
$srcY = ($this->height - $cropH) / 2;
}
$newImg = imagecreatetruecolor($this->resizeW, $this->resizeH);
imagecopyresampled($newImg, $this->im, 0, 0, $srcX, $srcY,
$this->resizeW, $this->resizeH, $cropW, $cropH);
} else {
// 等比縮放模式:完整保留畫面,留白處透明/背景色
if ($srcRatio >= $dstRatio) {
$newW = $this->resizeW;
$newH = $newW / $srcRatio;
} else {
$newH = $this->resizeH;
$newW = $newH * $srcRatio;
}
$newImg = imagecreatetruecolor($newW, $newH);
// 設定透明背景 (PNG/GIF)
if ($this->type == 'png' || $this->type == 'gif') {
imagealphablending($newImg, false);
imagesavealpha($newImg, true);
$transparent = imagecolorallocatealpha($newImg, 0,0,0,127);
imagefill($newImg, 0, 0, $transparent);
}
imagecopyresampled($newImg, $this->im, 0, 0, 0, 0, $newW, $newH, $this->width, $this->height);
}
// 輸出
switch ($this->type) {
case 'jpg': case 'jpeg': imagejpeg($newImg, $this->dstImg, 90); break;
case 'gif': imagegif($newImg, $this->dstImg); break;
case 'png': imagepng($newImg, $this->dstImg, 6); break;
}
imagedestroy($newImg);
imagedestroy($this->im);
}
}
?>
require_once 'ResizeImage.php';
// 等比縮放,最大寬 200、高 100
new ResizeImage("photo.jpg", 200, 100, 0, "thumb_photo.jpg");
// 裁切填滿 200x100
new ResizeImage("photo.jpg", 200, 100, 1, "thumb_crop.jpg");
imagefilter() 銳化、灰階、負片效果imagewebp())Imagick 擴充| 問題 | 解決 |
|---|---|
| 記憶體耗盡 | ini_set('memory_limit', '256M'); 或改用 Imagick 串流處理 |
| PNG 透明變黑 | 啟用 imagealphablending(false); imagesavealpha(true); |
| GIF 動畫只取第一幀 | GD 不支援多幀,需用 Imagick 或 ffmpeg |
| JPEG 品質差 | imagejpeg($im, $file, 90); 第三參數 0-100 |