功能單純,僅支援 JPG 輸出,縮放品質一般,適合快速原型。
<?php
class ResizeImage {
public $type, $width, $height, $resize_width, $resize_height, $cut, $srcimg, $dstimg, $im;
public function __construct($img, $wid, $hei, $c, $dstpath) {
$this->srcimg = $img;
$this->resize_width = $wid;
$this->resize_height = $hei;
$this->cut = $c;
$this->type = strtolower(pathinfo($img, PATHINFO_EXTENSION));
$this->initImg();
$this->dstimg = $dstpath;
$this->width = imagesx($this->im);
$this->height = imagesy($this->im);
$this->newImg();
imagedestroy($this->im);
}
private function initImg() {
$map = ['jpg'=>'imagecreatefromjpeg','gif'=>'imagecreatefromgif','png'=>'imagecreatefrompng'];
$func = $map[$this->type] ?? null;
if (!$func || !function_exists($func)) throw new Exception("不支援格式");
$this->im = $func($this->srcimg);
}
private function newImg() {
$rRatio = $this->resize_width / $this->resize_height;
$oRatio = $this->width / $this->height;
$newImg = imagecreatetruecolor($this->resize_width, $this->resize_height);
if ($this->cut) {
// 裁切模式(略)
} else {
// 等比縮放(略)
}
imagejpeg($newImg, $this->dstimg);
imagedestroy($newImg);
}
}
?>
imagezoom() 函式(推薦)支援 BMP、自動偵測格式、等比縮放置中、可指定背景填充色、編碼相容 Windows 中文路徑。
<?php
/**
* 高畫質縮圖函式
*
* @param string $srcimage 來源圖片路徑
* @param string $dstimage 輸出路徑
* @param int $dst_width 目標寬度
* @param int $dst_height 目標高度
* @param string $backgroundcolor 十六進位顏色碼(如 #FFFFFF)
* @return void
*/
function imagezoom(string $srcimage, string $dstimage, int $dst_width, int $dst_height, string $backgroundcolor): void {
// Windows 中文路徑編碼轉換
if (PHP_OS_FAMILY === 'Windows') {
$srcimage = iconv('UTF-8', 'GBK', $srcimage);
$dstimage = iconv('UTF-8', 'GBK', $dstimage);
}
// 建立目標畫布並填充背景色
$dstimg = imagecreatetruecolor($dst_width, $dst_height);
$color = imagecolorallocate($dstimg,
hexdec(substr($backgroundcolor, 1, 2)),
hexdec(substr($backgroundcolor, 3, 2)),
hexdec(substr($backgroundcolor, 5, 2))
);
imagefill($dstimg, 0, 0, $color);
// 讀取來源圖片資訊
if (!$info = @getimagesize($srcimage)) {
exit("來源檔案不存在: $srcimage");
}
[$src_w, $src_h] = $info;
// 依檔頭偵測格式並載入
$srcimg = loadImageBySignature($srcimage);
if (!$srcimg) exit("無法識別圖片格式");
// 計算等比縮放後尺寸與置中座標
$dst_x = $dst_y = 0;
$dst_w = $dst_width;
$dst_h = $dst_height;
if (($dst_width / $dst_height) > ($src_w / $src_h)) {
$dst_w = $src_w * ($dst_height / $src_h);
$dst_x = ($dst_width - $dst_w) / 2;
} elseif (($dst_width / $dst_height) < ($src_w / $src_h)) {
$dst_h = $src_h * ($dst_width / $src_w);
$dst_y = ($dst_height - $dst_h) / 2;
}
// 高品質重採樣
imagecopyresampled($dstimg, $srcimg, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
// 依副檔名輸出
$ext = strtolower(pathinfo($dstimage, PATHINFO_EXTENSION));
$outputMap = [
'jpg' => 'imagejpeg', 'jpeg' => 'imagejpeg',
'png' => 'imagepng', 'gif' => 'imagegif', 'bmp' => 'imagebmp'
];
if (!isset($outputMap[$ext])) exit("不支援的輸出格式: $ext");
$outputMap[$ext]($dstimg, $dstimage);
imagedestroy($dstimg);
imagedestroy($srcimg);
}
/** 依檔頭 Magic Number 偵測格式並載入 */
function loadImageBySignature(string $file) {
$signatures = [
'474946' => "imagecreatefromgif('$file')", // GIF
'FFD8FF' => "imagecreatefromjpeg('$file')", // JPEG
'424D' => "imagecreatefrombmp('$file')", // BMP
'89504E' => "imagecreatefrompng('$file')", // PNG
];
$fp = fopen($file, 'rb');
$header = fread($fp, 3);
fclose($fp);
$hex = strtoupper(bin2hex($header));
foreach ($signatures as $sig => $code) {
if (str_starts_with($hex, $sig)) return eval("return $code;");
}
return false;
}
/** BMP 載入(PHP 內建無此函式) */
function imagecreatefrombmp(string $filename) {
// 完整 BMP 解析邏輯見原始碼,此處省略
// 回傳 GD 圖片資源
}
/** BMP 輸出(PHP 內建無此函式) */
function imagebmp($im, $fn = false) {
// 完整 BMP 寫入邏輯見原始碼
return true;
}
// 使用範例
imagezoom('1.jpg', '2.jpg', 400, 300, '#FFFFFF');
?>
| 項目 | 基礎版 ResizeImage | 高畫質版 imagezoom |
|---|---|---|
| 支援格式 | JPG/GIF/PNG | JPG/GIF/PNG/BMP |
| 輸出格式 | 僅 JPEG | 依副檔名自動對應 |
| 縮放品質 | 普通 | 高品質 resample + 置中 |
| 背景填充 | 無(預設黑底) | 可自訂十六進位顏色 |
| 中文路徑 | 不支援 | Windows 自動 iconv 轉碼 |
| 程式結構 | 類別式 | 函式式 |
簡單專案可用基礎版;正式產品環境建議採用高畫質版或直接引入 Intervention/Image,獲得更完善的錯誤處理、單元測試與框架整合。