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

PHP GD 庫建立圖片縮略圖完整實作

     編輯:PHP 綜合知識

完整流程:上傳 → 縮圖 → 儲存 → 顯示

1. 上傳表單 (HTML)

<form enctype="multipart/form-data" action="upload.php" method="post">
    <input name="upfile" type="file" accept="image/*"><br>
    <input type="submit" value="上傳並生成縮圖">
</form>

2. 處理腳本 (upload.php)

<?php
// 設定
$uploadDir = 'uploads/';
$thumbDir = 'thumbs/';
$maxWidth = 300;
$maxHeight = 300;
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];

if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true);
if (!is_dir($thumbDir)) mkdir($thumbDir, 0755, true);

// 檢查上傳
if (!isset($_FILES['upfile']) || $_FILES['upfile']['error'] !== UPLOAD_ERR_OK) {
    die("上傳失敗: " . ($_FILES['upfile']['error'] ?? '無檔案'));
}

$tmpName = $_FILES['upfile']['tmp_name'];
$origName = basename($_FILES['upfile']['name']);
$mime = mime_content_type($tmpName);

if (!in_array($mime, $allowedTypes)) {
    die("不支援的檔案類型: $mime");
}

// 產生安全檔名
$ext = ['image/jpeg'=>'jpg', 'image/png'=>'png', 'image/gif'=>'gif', 'image/webp'=>'webp'][$mime];
$safeName = bin2hex(random_bytes(8)) . ".$ext";
$destPath = $uploadDir . $safeName;
$thumbPath = $thumbDir . 'thumb_' . $safeName;

// 移動上傳檔
if (!move_uploaded_file($tmpName, $destPath)) {
    die("檔案儲存失敗");
}

// === 核心縮圖邏輯 ===
list($srcW, $srcH, $srcType) = getimagesize($destPath);

// 計算目標尺寸 (維持比例)
$ratio = $srcW / $srcH;
if ($maxWidth / $maxHeight > $ratio) {
    $dstW = (int)($maxHeight * $ratio);
    $dstH = $maxHeight;
} else {
    $dstW = $maxWidth;
    $dstH = (int)($maxWidth / $ratio);
}

// 建立目標畫布
$dstImg = imagecreatetruecolor($dstW, $dstH);

// 載入來源圖片
switch ($srcType) {
    case IMAGETYPE_JPEG:  $srcImg = imagecreatefromjpeg($destPath); break;
    case IMAGETYPE_PNG:   $srcImg = imagecreatefrompng($destPath); break;
    case IMAGETYPE_GIF:   $srcImg = imagecreatefromgif($destPath); break;
    case IMAGETYPE_WEBP:  $srcImg = imagecreatefromwebp($destPath); break;
    default: die("不支援的圖片格式");
}

// 保持透明度 (PNG/GIF/WEBP)
if (in_array($srcType, [IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_WEBP])) {
    imagealphablending($dstImg, false);
    imagesavealpha($dstImg, true);
}

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

// 儲存縮圖 (依原格式)
switch ($srcType) {
    case IMAGETYPE_JPEG:  imagejpeg($dstImg, $thumbPath, 85); break;
    case IMAGETYPE_PNG:   imagepng($dstImg, $thumbPath, 9); break;
    case IMAGETYPE_GIF:   imagegif($dstImg, $thumbPath); break;
    case IMAGETYPE_WEBP:  imagewebp($dstImg, $thumbPath, 85); break;
}

// 釋放資源
imagedestroy($srcImg);
imagedestroy($dstImg);

// 輸出結果
echo "上傳成功!
"; echo "<img src='$destPath' alt='原圖' style='max-width:300px'> "; echo "<img src='$thumbPath' alt='縮圖' style='max-width:300px'>"; ?>

進階:多尺寸縮圖批次生成

function generateThumbnails($srcPath, $destDir, $sizes = []) {
    // $sizes = ['small'=>[150,150], 'medium'=>[300,300], 'large'=>[800,600]]
    list($w, $h, $type) = getimagesize($srcPath);
    $src = loadImageByType($srcPath, $type);
    
    foreach ($sizes as $name => [$maxW, $maxH]) {
        $ratio = $w / $h;
        if ($maxW / $maxH > $ratio) {
            $dstW = (int)($maxH * $ratio);
            $dstH = $maxH;
        } else {
            $dstW = $maxW;
            $dstH = (int)($maxW / $ratio);
        }
        
        $dst = imagecreatetruecolor($dstW, $dstH);
        if (in_array($type, [IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_WEBP])) {
            imagealphablending($dst, false);
            imagesavealpha($dst, true);
        }
        imagecopyresampled($dst, $src, 0, 0, 0, 0, $dstW, $dstH, $w, $h);
        
        $ext = getExtByType($type);
        $outPath = "$destDir/{$name}_$dstW" . "x$dstH.$ext";
        saveImageByType($dst, $outPath, $type);
        imagedestroy($dst);
    }
    imagedestroy($src);
    return true;
}

效能優化建議

優化點方案
大量上傳異步佇列處理,立即回應用戶
重複尺寸請求快取機制:檢查縮圖是否存在再生成
記憶體峰值分塊處理、及時 imagedestroy
CPU 密集考慮 ImageMagick (imagick 擴展) 效能更佳

ImageMagick 對比

// Imagick 版本 (更簡潔、效能更好、格式支援更多)
$imagick = new Imagick($srcPath);
$imagick->thumbnailImage(300, 300, true, true); // true=維持比例
$imagick->writeImage($thumbPath);
$imagick->destroy();

GD 庫縮圖是 PHP 內建零依賴方案,掌握 imagecopyresampled 核心函式與透明度保持技巧,即可應對大多數縮圖需求。

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