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

PHP GD 圖片旋轉 90 度完整實作與常見坑點

     編輯:PHP 綜合知識

函數簽名與說明

/**
 * 旋轉圖片指定角度並另存新檔
 *
 * @param string $srcPath  來源圖片完整路徑
 * @param string $destPath 目標儲存路徑
 * @param int    $degrees  旋轉角度(預設 90,順時針)
 * @return bool 成功返回 true,失敗 false
 */
function rotateImage(string $srcPath, string $destPath, int $degrees = 90): bool

核心實作程式碼

<?php
function rotateImage(string $srcPath, string $destPath, int $degrees = 90): bool
{
    // 1. 讀取圖片資訊,判斷格式
    $info = @getimagesize($srcPath);
    if ($info === false) {
        error_log("rotateImage: 無法讀取圖片 {$srcPath}");
        return false;
    }

    // 2. 根據 MIME 類型建立 GD 資源
    $createFunc = match ($info[2]) {
        IMAGETYPE_GIF  => 'imagecreatefromgif',
        IMAGETYPE_JPEG => 'imagecreatefromjpeg',
        IMAGETYPE_PNG  => 'imagecreatefrompng',
        IMAGETYPE_WEBP => 'imagecreatefromwebp',
        default        => null,
    };

    if ($createFunc === null) {
        error_log("rotateImage: 不支援的圖片格式 {$info['mime']}");
        return false;
    }

    $srcImg = $createFunc($srcPath);
    if ($srcImg === false) {
        error_log("rotateImage: GD 建立資源失敗 {$srcPath}");
        return false;
    }

    // 3. 執行旋轉(背景色設為透明/白)
    $bgColor = imagecolorallocatealpha($srcImg, 255, 255, 255, 127); // 透明白
    $rotated = imagerotate($srcImg, $degrees, $bgColor);

    if ($rotated === false) {
        imagedestroy($srcImg);
        error_log("rotateImage: imagerotate 失敗");
        return false;
    }

    // 4. 另存為 JPEG(品質 90),可依需求改 PNG/WebP
    $result = imagejpeg($rotated, $destPath, 90);

    // 5. 釋放記憶體
    imagedestroy($srcImg);
    imagedestroy($rotated);

    return $result;
}

// 使用範例
rotateImage('/var/www/uploads/photo.jpg', '/var/www/uploads/photo_rotated.jpg', 90);
?>

關鍵技術點深度解析

1. 格式自動偵測

使用 getimagesize() 回傳的索引 2(IMAGETYPE_* 常量)判斷格式,比副檔名更可靠。支援 GIF/JPEG/PNG/WebP 四大主流格式。

2. 背景色處理

imagerotate() 第三參數為旋轉後露出區域的填充色。使用 imagecolorallocatealpha() 設定 alpha=127(全透明),避免 PNG/WebP 出現黑邊;若輸出 JPEG,透明會自動轉白。

3. 記憶體管理

GD 資源佔用系統記憶體,**務必成對呼叫 imagedestroy() 釋放**,否則長時間運行的腳本(如批次處理)會導致記憶體洩漏、OOM Killer 介入。

4. 錯誤處理策略

  • 使用 @ 抑制 GD 函數警告,改由回傳值判斷
  • 統一輸出 error_log(),便於集中監控
  • 回傳 bool 而非拋出例外,適合工具型函數

常見坑點與解決方案

問題原因解決
旋轉後圖片變黑/有黑框背景色預設黑色,透明通道處理不當指定透明背景色 imagecolorallocatealpha(..., 127)
PNG 透明背景變黑輸出 JPEG 不支援透明輸出改用 imagepng() 或預先填白底
大圖旋轉記憶體爆炸GD 解碼後佔用寬×高×4 bytes分塊處理、增加 memory_limit、改用 Imagick
旋轉角度非 90 倍數畫質差雙線性插值導致模糊僅允許 90/180/270 度,或啟用 imagesetinterpolation()
EXIF 方向標籤未處理手機照片含 Orientation 標籤上傳前用 exif_read_data() 讀取並自動旋轉

進階替代方案:Imagick

若專案已安裝 ImageMagick + php-imagick,建議改用:

$imagick = new Imagick($srcPath);
$imagick->rotateImage(new ImagickPixel('none'), $degrees); // none = 透明
$imagick->writeImage($destPath);
$imagick->destroy();

優勢:支援更多格式、自動處理 EXIF Orientation、大圖效能更好、API 更現代化。

結語

PHP GD 旋轉圖片看似簡單,實則涉及格式偵測、透明度處理、記憶體管理、EXIF 相容等細節。封裝成可複用函數並加入完善錯誤處理,才能在生產環境穩定運行。

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