JPEG 縮放直觀,但 PNG 含透明通道 (Alpha) 時,若直接用 imagecopyresampled 會導致透明區域變黑或變白,必須顯式處理 Alpha 通道。
<?php
// 1. 載入源圖
$srcImg = imagecreatefrompng('./source.png');
$srcWidth = imagesx($srcImg);
$srcHeight = imagesy($srcImg);
// 2. 計算目標尺寸 (例:縮小一半)
$newWidth = round($srcWidth / 2);
$newHeight = round($srcHeight / 2);
// 3. 建立真彩色目標畫布
$newImg = imagecreatetruecolor($newWidth, $newHeight);
// 4. 關鍵:分配全透明色並填充畫布
$transparent = imagecolorallocatealpha($newImg, 0, 0, 0, 127); // 127 = 完全透明
imagefill($newImg, 0, 0, $transparent);
// 5. 關鍵:啟用 Alpha 混合模式與保存完整 Alpha 通道
imagealphablending($newImg, true);
imagesavealpha($newImg, true);
// 6. 執行重採樣縮放
imagecopyresampled($newImg, $srcImg, 0, 0, 0, 0, $newWidth, $newHeight, $srcWidth, $srcHeight);
// 7. 輸出 PNG
imagepng($newImg, './thumb.png');
// 8. 釋放資源
imagedestroy($srcImg);
imagedestroy($newImg);
| 函數 | 作用 |
|---|---|
imagecolorallocatealpha | 分配含 Alpha 的顏色 (0-127,127 完全透明) |
imagefill | 以透明色填充整個畫布 |
imagealphablending | 開啟混合模式,讓來源像素 Alpha 與目標融合 |
imagesavealpha | 輸出 PNG 時保存完整 Alpha 通道資訊 (關鍵!) |
resampled。imagecreatefrompng 會失敗,需根據副檔名/MIME 動態選擇 createfromjpeg 等。function resizePngKeepTransparency($srcPath, $dstPath, $maxWidth, $maxHeight) {
$src = imagecreatefrompng($srcPath);
$sw = imagesx($src); $sh = imagesy($src);
$ratio = min($maxWidth/$sw, $maxHeight/$sh);
$nw = (int)($sw * $ratio); $nh = (int)($sh * $ratio);
$dst = imagecreatetruecolor($nw, $nh);
$tp = imagecolorallocatealpha($dst, 0,0,0,127);
imagefill($dst,0,0,$tp);
imagealphablending($dst,true);
imagesavealpha($dst,true);
imagecopyresampled($dst,$src,0,0,0,0,$nw,$nh,$sw,$sh);
imagepng($dst,$dstPath);
imagedestroy($src); imagedestroy($dst);
}
四行關鍵代碼 (allocatealpha、fill、alphablending、savealpha) 即可完美解決 PNG 縮放透明度丟失問題。封裝為通用函數後,專案中所有縮略圖生成均可復用,確保視覺一致性。