首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 等比例生成縮略圖:保持長寬比、支援 JPEG/PNG/GIF、可指定最大寬高

     編輯:PHP 相關知識

核心函式

<?php
/**
 * 等比例縮放圖片
 * @param string $srcPath 來源檔案路徑
 * @param int $maxW 最大寬度
 * @param int $maxH 最大高度
 * @param string $destPath 輸出路徑(預設覆蓋來源)
 * @param int $quality JPEG 品質 1-100
 * @return bool
 */
function resizeProportional(string $srcPath, int $maxW, int $maxH, string $destPath = '', int $quality = 90): bool
{
    if (!file_exists($srcPath)) return false;

    $destPath = $destPath ?: $srcPath;
    [$w, $h, $type] = getimagesize($srcPath);

    // 無需縮放
    if ($w <= $maxW && $h <= $maxH) {
        return $srcPath !== $destPath ? copy($srcPath, $destPath) : true;
    }

    // 計算縮放比例
    $ratio = min($maxW / $w, $maxH / $h);
    $newW = (int)($w * $ratio);
    $newH = (int)($h * $ratio);

    // 建立來源圖片資源
    $src = match ($type) {
        IMAGETYPE_JPEG => imagecreatefromjpeg($srcPath),
        IMAGETYPE_PNG  => imagecreatefrompng($srcPath),
        IMAGETYPE_GIF  => imagecreatefromgif($srcPath),
        default        => return false,
    };

    // 建立目標畫布(真彩色)
    $dst = imagecreatetruecolor($newW, $newH);

    // PNG/GIF 保持透明度
    if ($type === IMAGETYPE_PNG || $type === IMAGETYPE_GIF) {
        imagealphablending($dst, false);
        imagesavealpha($dst, true);
        $transparent = imagecolorallocatealpha($dst, 255, 255, 255, 127);
        imagefilledrectangle($dst, 0, 0, $newW, $newH, $transparent);
    }

    // 高品質重採樣
    imagecopyresampled($dst, $src, 0, 0, 0, 0, $newW, $newH, $w, $h);

    // 輸出
    $result = match ($type) {
        IMAGETYPE_JPEG => imagejpeg($dst, $destPath, $quality),
        IMAGETYPE_PNG  => imagepng($dst, $destPath),
        IMAGETYPE_GIF  => imagegif($dst, $destPath),
        default        => false,
    };

    imagedestroy($src);
    imagedestroy($dst);
    return $result;
}

使用範例

<?php
// 產生最大 300x300 縮圖
resizeProportional('uploads/photo.jpg', 300, 300, 'uploads/thumb_photo.jpg');

// 批次處理目錄
foreach (glob('uploads/*.{jpg,png,gif}', GLOB_BRACE) as $file) {
    $thumb = 'thumbs/' . basename($file);
    resizeProportional($file, 200, 200, $thumb);
}

關鍵細節解析

細節處理方式
長寬比保持min($maxW/$w, $maxH/$h) 取較小比例,確保不超出任一邊界
不放大小圖先判斷 $w <= $maxW && $h <= $maxH 直接複製
PNG/GIF 透明度關閉混色、啟用 alpha 儲存、建立透明底
畫質使用 imagecopyresampled 而非 imagecopyresized
記憶體處理完立即 imagedestroy() 釋放 GD 資源

進階:裁切模式

若需「填滿區域並裁切多餘」(如封面圖),改用裁切邏輯:

function cropCover($srcPath, $targetW, $targetH, $destPath) {
    [$w, $h, $type] = getimagesize($srcPath);
    $srcRatio = $w / $h;
    $dstRatio = $targetW / $targetH;

    if ($srcRatio > $dstRatio) {
        // 來源較寬 → 裁切左右
        $cropH = $h;
        $cropW = $h * $dstRatio;
        $x = ($w - $cropW) / 2;
        $y = 0;
    } else {
        // 來源較高 → 裁切上下
        $cropW = $w;
        $cropH = $w / $dstRatio;
        $x = 0;
        $y = ($h - $cropH) / 2;
    }
    // 後續同 resizeProportional,但來源區域為 ($x, $y, $cropW, $cropH)
}

常見問題

  • 記憶體不足:大圖(>10MP)處理需調大 memory_limit 或分塊處理。
  • 輸出模糊:確認用 imagecopyresampled,且 JPEG 品質 ≥ 80。
  • 透明背景變黑PNG/GIF 必須設定 imagesavealpha(true) 並建立透明底。

這個函式已在多個專案的上傳流程中穩定運行,支援三大常見格式,程式碼簡潔易維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved