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

PHP 縮圖類別實作比較:基礎版 vs 高畫質版(含 BMP 支援)

     編輯:PHP 相關知識

版本一:基礎 ResizeImage 類別

功能單純,僅支援 JPG 輸出,縮放品質一般,適合快速原型。

<?php
class ResizeImage {
    public $type, $width, $height, $resize_width, $resize_height, $cut, $srcimg, $dstimg, $im;

    public function __construct($img, $wid, $hei, $c, $dstpath) {
        $this->srcimg = $img;
        $this->resize_width = $wid;
        $this->resize_height = $hei;
        $this->cut = $c;
        $this->type = strtolower(pathinfo($img, PATHINFO_EXTENSION));
        $this->initImg();
        $this->dstimg = $dstpath;
        $this->width = imagesx($this->im);
        $this->height = imagesy($this->im);
        $this->newImg();
        imagedestroy($this->im);
    }

    private function initImg() {
        $map = ['jpg'=>'imagecreatefromjpeg','gif'=>'imagecreatefromgif','png'=>'imagecreatefrompng'];
        $func = $map[$this->type] ?? null;
        if (!$func || !function_exists($func)) throw new Exception("不支援格式");
        $this->im = $func($this->srcimg);
    }

    private function newImg() {
        $rRatio = $this->resize_width / $this->resize_height;
        $oRatio = $this->width / $this->height;
        $newImg = imagecreatetruecolor($this->resize_width, $this->resize_height);

        if ($this->cut) {
            // 裁切模式(略)
        } else {
            // 等比縮放(略)
        }
        imagejpeg($newImg, $this->dstimg);
        imagedestroy($newImg);
    }
}
?>

版本二:高畫質 imagezoom() 函式(推薦)

支援 BMP、自動偵測格式、等比縮放置中、可指定背景填充色、編碼相容 Windows 中文路徑。

<?php
/**
 * 高畫質縮圖函式
 *
 * @param string $srcimage 來源圖片路徑
 * @param string $dstimage 輸出路徑
 * @param int    $dst_width 目標寬度
 * @param int    $dst_height 目標高度
 * @param string $backgroundcolor 十六進位顏色碼(如 #FFFFFF)
 * @return void
 */
function imagezoom(string $srcimage, string $dstimage, int $dst_width, int $dst_height, string $backgroundcolor): void {
    // Windows 中文路徑編碼轉換
    if (PHP_OS_FAMILY === 'Windows') {
        $srcimage = iconv('UTF-8', 'GBK', $srcimage);
        $dstimage = iconv('UTF-8', 'GBK', $dstimage);
    }

    // 建立目標畫布並填充背景色
    $dstimg = imagecreatetruecolor($dst_width, $dst_height);
    $color = imagecolorallocate($dstimg,
        hexdec(substr($backgroundcolor, 1, 2)),
        hexdec(substr($backgroundcolor, 3, 2)),
        hexdec(substr($backgroundcolor, 5, 2))
    );
    imagefill($dstimg, 0, 0, $color);

    // 讀取來源圖片資訊
    if (!$info = @getimagesize($srcimage)) {
        exit("來源檔案不存在: $srcimage");
    }
    [$src_w, $src_h] = $info;

    // 依檔頭偵測格式並載入
    $srcimg = loadImageBySignature($srcimage);
    if (!$srcimg) exit("無法識別圖片格式");

    // 計算等比縮放後尺寸與置中座標
    $dst_x = $dst_y = 0;
    $dst_w = $dst_width;
    $dst_h = $dst_height;

    if (($dst_width / $dst_height) > ($src_w / $src_h)) {
        $dst_w = $src_w * ($dst_height / $src_h);
        $dst_x = ($dst_width - $dst_w) / 2;
    } elseif (($dst_width / $dst_height) < ($src_w / $src_h)) {
        $dst_h = $src_h * ($dst_width / $src_w);
        $dst_y = ($dst_height - $dst_h) / 2;
    }

    // 高品質重採樣
    imagecopyresampled($dstimg, $srcimg, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $src_w, $src_h);

    // 依副檔名輸出
    $ext = strtolower(pathinfo($dstimage, PATHINFO_EXTENSION));
    $outputMap = [
        'jpg' => 'imagejpeg', 'jpeg' => 'imagejpeg',
        'png' => 'imagepng', 'gif' => 'imagegif', 'bmp' => 'imagebmp'
    ];
    if (!isset($outputMap[$ext])) exit("不支援的輸出格式: $ext");
    $outputMap[$ext]($dstimg, $dstimage);

    imagedestroy($dstimg);
    imagedestroy($srcimg);
}

/** 依檔頭 Magic Number 偵測格式並載入 */
function loadImageBySignature(string $file) {
    $signatures = [
        '474946' => "imagecreatefromgif('$file')",     // GIF
        'FFD8FF' => "imagecreatefromjpeg('$file')",    // JPEG
        '424D'   => "imagecreatefrombmp('$file')",     // BMP
        '89504E' => "imagecreatefrompng('$file')",     // PNG
    ];
    $fp = fopen($file, 'rb');
    $header = fread($fp, 3);
    fclose($fp);
    $hex = strtoupper(bin2hex($header));
    foreach ($signatures as $sig => $code) {
        if (str_starts_with($hex, $sig)) return eval("return $code;");
    }
    return false;
}

/** BMP 載入(PHP 內建無此函式) */
function imagecreatefrombmp(string $filename) {
    // 完整 BMP 解析邏輯見原始碼,此處省略
    // 回傳 GD 圖片資源
}

/** BMP 輸出(PHP 內建無此函式) */
function imagebmp($im, $fn = false) {
    // 完整 BMP 寫入邏輯見原始碼
    return true;
}

// 使用範例
imagezoom('1.jpg', '2.jpg', 400, 300, '#FFFFFF');
?>

兩版本差異總結

項目基礎版 ResizeImage高畫質版 imagezoom
支援格式JPG/GIF/PNGJPG/GIF/PNG/BMP
輸出格式僅 JPEG依副檔名自動對應
縮放品質普通高品質 resample + 置中
背景填充無(預設黑底)可自訂十六進位顏色
中文路徑不支援Windows 自動 iconv 轉碼
程式結構類別式函式式

結論

簡單專案可用基礎版;正式產品環境建議採用高畫質版或直接引入 Intervention/Image,獲得更完善的錯誤處理、單元測試與框架整合。

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