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

PHP 圖片等比例縮放實作:GD 函數版

     編輯:PHP 相關知識

PHP 圖片等比例縮放實作:GD 函數版

利用 PHP GD 擴充套件實作圖片等比例縮放,適用於縮圖生成、上傳預覽等場景。本文提供完整可執行腳本,支援 JPEG 格式,並說明如何擴充支援 PNG/GIF/WebP 及品質控制。

基礎版:固定縮放比例 (30%)

<?php
// 設定
$srcPath = __DIR__ . '/q.jpg';   // 來源圖片
$dstPath = __DIR__ . '/q1.jpg';  // 輸出圖片
$scale   = 0.3;                  // 縮放比例 (30%)

// 1. 取得原始尺寸
list($srcW, $srcH) = getimagesize($srcPath);
if (!$srcW || !$srcH) {
    die('無法讀取圖片或格式不支援');
}

// 2. 計算目標尺寸
$dstW = (int)($srcW * $scale);
$dstH = (int)($srcH * $scale);

// 3. 建立真彩色目標畫布
$dstImg = imagecreatetruecolor($dstW, $dstH);

// 4. 載入來源圖片 (JPEG)
$srcImg = imagecreatefromjpeg($srcPath);

// 5. 等比例複製並重取樣 (imagecopyresampled 品質優於 imagecopyresized)
imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH);

// 6. 輸出 JPEG (品質 85)
imagejpeg($dstImg, $dstPath, 85);

// 7. 釋放記憶體
imagedestroy($dstImg);
imagedestroy($srcImg);

echo "縮圖生成成功:{$dstPath} ({$dstW}x{$dstH})";
?>

進階版:支援多格式、自適應長邊、品質參數化

<?php
/**
 * 等比例縮放圖片 (支援 JPEG/PNG/GIF/WebP)
 * @param string $srcPath  來源路徑
 * @param string $dstPath  目標路徑
 * @param int    $maxDim   最大長邊像素 (0 表示不限制)
 * @param int    $quality  輸出品質 1-100 (僅 JPEG/WebP 生效)
 * @return array ['width'=>, 'height'=>, 'type'=>] 或 false
 */
function smartResize($srcPath, $dstPath, $maxDim = 800, $quality = 85) {
    // 1. 偵測圖片類型
    $info = getimagesize($srcPath);
    if (!$info) return false;
    [$srcW, $srcH, $type] = $info;

    // 2. 計算目標尺寸
    if ($maxDim > 0) {
        $ratio = min($maxDim / $srcW, $maxDim / $srcH, 1); // 不放大
        $dstW = (int)($srcW * $ratio);
        $dstH = (int)($srcH * $ratio);
    } else {
        $dstW = $srcW; $dstH = $srcH;
    }

    // 3. 載入來源 (依類型分派)
    $createFrom = [
        IMAGETYPE_JPEG  => 'imagecreatefromjpeg',
        IMAGETYPE_PNG   => 'imagecreatefrompng',
        IMAGETYPE_GIF   => 'imagecreatefromgif',
        IMAGETYPE_WEBP  => 'imagecreatefromwebp',
    ];
    if (!isset($createFrom[$type])) return false;
    $srcImg = $createFrom[$type]($srcPath);

    // 4. 建立目標畫布 (保留透明度)
    $dstImg = imagecreatetruecolor($dstW, $dstH);
    if ($type === IMAGETYPE_PNG || $type === IMAGETYPE_GIF || $type === IMAGETYPE_WEBP) {
        imagealphablending($dstImg, false);
        imagesavealpha($dstImg, true);
        $transparent = imagecolorallocatealpha($dstImg, 255, 255, 255, 127);
        imagefill($dstImg, 0, 0, $transparent);
    }

    // 5. 高品質重取樣
    imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH);

    // 6. 輸出 (依類型分派)
    $saveAs = [
        IMAGETYPE_JPEG => fn() => imagejpeg($dstImg, $dstPath, $quality),
        IMAGETYPE_PNG  => fn() => imagepng($dstImg, $dstPath, 9), // PNG 壓縮等級 0-9
        IMAGETYPE_GIF  => fn() => imagegif($dstImg, $dstPath),
        IMAGETYPE_WEBP => fn() => imagewebp($dstImg, $dstPath, $quality),
    ];
    $saveAs[$type]();

    // 7. 清理
    imagedestroy($srcImg);
    imagedestroy($dstImg);

    return ['width' => $dstW, 'height' => $dstH, 'type' => $type];
}

// 使用範例
$result = smartResize('upload/photo.jpg', 'thumb/photo.jpg', 400, 80);
if ($result) {
    echo "成功:{$result['width']}x{$result['height']}";
} else {
    echo "失敗:格式不支援或檔案損壞";
}
?>

關鍵函數差異對照

函數品質速度適用場景
imagecopyresized低 (鋸齒明顯)快極大量批次、即時預覽
imagecopyresampled高 (雙立方插值)中正式縮圖、使用者頭像、商品圖

常見問題與解決

  1. 記憶體不足:大圖 (如 5000x5000) 解碼需大量記憶體。解決:ini_set('memory_limit', '256M') 或分塊處理 (Imagick 更適合)。
  2. PNG/GIF 透明變黑:必須啟用 imagealphablending(false) + imagesavealpha(true) 並填充透明色。
  3. WebP 不支援:需 PHP 7.0+ 且編譯時 --with-webp,或改用 Imagick。
  4. EXIF 方向自動修正:手機拍攝照片含 Orientation 標籤,GD 不自動旋轉。建議用 exif_read_data() 讀取並手動 imagerotate(),或改用 Imagick autoOrientImage()。

生產環境建議:改用 Imagick

ImageMagick (Imagick 擴充套件) 效能更好、格式支援更全、自動處理 EXIF 方向、記憶體管理更優。同等功能程式碼更簡潔:

$im = new Imagick($srcPath);
$im->thumbnailImage($maxDim, $maxDim, true); // true = 等比例
$im->writeImage($dstPath);

GD 適合輕量環境、無法安裝擴充套件的虛擬主機;正式專案強烈建議使用 Imagick。

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