PHP - 画像リサイズ

PHP - 画像リサイズ

画像を表示するとき、多くのサイズの画像を用意するのは大変。そこで、画像をリサイズするプログラムを試してみる。以下のサンプルは、画像処理の部分を簡潔に見せる為にセキュリティー上問題のあるコードになっているかもしれません。また、パラメータ処理の部分は本題の部分ではないためブラックボックスになっています。

オリジナル

拡大

縮小

コード

<?php
/**
 * 画像
 * @package Gadgety
 * @create  2005.03.30 
 * <pre>
 * Usage:  imgview?file=FILENAME&size=WxH&flag=FLAG
 *    file :   表示したい画像のファイル名を指定
 *    size   リサイズや表示可能最大サイズを指定
 *    flag   resize => size で指定したサイズにリサイズ
 *           max    => size で指定したサイズより大きい場合にはリサイズ
 * </pre>
 */
require_once("Gadgety/PramCheck.php");

// リクエスト値
define("REQ_FNAME",     "file");
define("REQ_FLAG",      "flag");
define("REQ_SIZE",      "size");

// フラグ
define("FLAG_MAX",      "max");
define("FLAG_RESIZE",   "resize");
define("IMG_RESIZE",    3);
define("IMG_HAVE",      1);
define("IMG_NONE",      0);

// 画像
define("REAL_PATH",     "/home/who/tmp/images");
define("DEF_QUALITY",   "75");
define("FMT_GIF",       1);
define("FMT_JPG",       2);
define("FMT_PNG",       3);

/**
 * 描画クラス
 */
class ViewImage extends CheckRequest {
    /**
     * ファイル名
     *
     * @var    string
     */
    var $sFilename = "";

    /**
     * 処理
     *
     * @var    string
     */
    var $sFlag = "";

    /**
     * サイズ
     *
     * @var    string
     */
    var $sSize = "";

    /**
     * 画像形式
     *
     * @var    integer
     */
    var $iFormat = 0;

    /**
     * 画像MIME形式
     *
     * @var    string
     */
    var $sMimeType = "";

    /**
     * 画像ステータス
     *
     * @var    integer
     */
    var $iImage = IMG_NONE;

    /**
     * 画像サイズ
     *
     * @var    interger
     */
    var $iOrgWidth  = 0;
    var $iOrgHeight = 0;
    var $iNewWidth  = 0;
    var $iNewHeight = 0;

    /**
     * 画像クオリティー
     *
     * @var    interger
     */
    var $iQuality = DEF_QUALITY;

    /**
     * コンストラクタ
     */
    function ViewImage() {
        // リクエスト値のチェック
        ...

        // リクエスト値のセット
        ...
    }

    /**
     * 画像情報の取得
     */
    function getImageInfo() {
        if ( !is_file($this->sFilename) ) {
            $this->sFilename = REAL_PATH."/".$this->sSize.".gif";
            if ( !is_file($this->sFilename) ) {
                $this->sFilename = REAL_PATH."/200x150.gif";
            }
            $this->sFlag = "";
            $this->sSize = "";
            $this->iImage = IMG_NONE;
        } else {
            $this->iImage = IMG_HAVE;
        }
        $aryInfo = GetImageSize($this->sFilename);
        $this->iOrgWidth  = $aryInfo[0];
        $this->iOrgHeight = $aryInfo[1];
        $this->iFormat    = $aryInfo[2];
        $this->sMimeType  = $aryInfo['mime'];
    }

    /**
     * JPEGクオリティの設定
     */
    function setImageQuality($iQuality) {
        $this->iQuality = $iQuality;
    }

    /**
     * 画像サイズのセット
     */
    function setNewSize() {
        ereg("^([0-9]{2,4})x([0-9]{2,4})$", $this->sSize, $arySize);
        if ( isset($arySize[1]) && isset($arySize[2]) ) {
            // 指定サイズにリサイズ
            if ( $this->sFlag == FLAG_RESIZE ) {    
                if ( $this->iOrgWidth > $this->iOrgHeight ) {
                    $this->iNewWidth  = $arySize[1];
                    $this->iNewHeight
                        = $this->iOrgHeight * $arySize[1] / $this->iOrgWidth;
                } else {
                    $this->iNewWidth 
                        = $this->iOrgWidth * $arySize[2] / $this->iOrgHeight;
                    $this->iNewHeight = $arySize[2];
                }
                $this->iImage = IMG_RESIZE;
                return;
            }
            // 最大値オーバーの場合リサイズ
            else if ($this->sFlag == FLAG_MAX) {
                $iWidthRate  = $this->iOrgWidth / $arySize[1];
                $iHeightRate = $this->iOrgHeight / $arySize[2];
                if ( ($iWidthRate > 1) || ($iHeightRate > 1) ) {
                    if  ($iWidthRate > $iHeightRate) {
                        $this->iNewWidth  = $arySize[1];
                        $this->iNewHeight
                          = $this->iOrgHeight * $arySize[1] / $this->iOrgWidth;
                        $this->iImage = IMG_RESIZE;
                    } else {
                        $this->iNewWidth 
                          = $this->iOrgWidth * $arySize[2] / $this->iOrgHeight;
                        $this->iNewHeight = $arySize[2];
                        $this->iImage = IMG_RESIZE;
                    }
                    return;
                }
            }
        }
        // その他の条件の場合
        $this->iNewWidth  = $this->iOrgWidth;
        $this->iNewHeight = $this->iOrgHeight;
    }

    /**
     * 画像表示
     */
    function showImage() {
        if ( ($this->iImage == IMG_NONE) || ($this->iImage == IMG_HAVE) ) {
            $fpImagefile  = fopen($this->sFilename, "rb");
            if ($fpImagefile) {
                header("Content-type: ".$this->sMimeType);
                fpassthru($fpImagefile);
                fclose($fpImagefile);
            }
            return;
        }
        $src_img = "";
        $des_img = "";
        switch($this->iFormat) {
            case FMT_GIF:
                $src_img = ImageCreateFromGif($this->sFilename);
                $trans   = ImageColorTransparent($src_img);
                $des_img = ImageCreate($this->iNewWidth, $this->iNewHeight);
                ImagePaletteCopy($des_img, $src_img);
                if ($trans >= 0) {
                    ImageFill($des_img, 0, 0, $trans);
                }
                // 画像の変換
                ImageCopyResized($des_img, $src_img, 0, 0, 0, 0,
                         $this->iNewWidth, $this->iNewHeight,
                         $this->iOrgWidth, $this->iOrgHeight);
                ImageColorTransparent($des_img, $trans);
                // 画像の描画
                if (function_exists('ImageGif')) {
                    header("Content-type: ".$this->sMimeType);
                    ImageGif($des_img);
                } else {
                    header("Content-type: image/jpeg");
                    ImageJpeg($des_img, "", $this->iQuality);
                }
                break;

            case FMT_JPG:
                $src_img = ImageCreateFromJpeg($this->sFilename);
                $des_img = ImageCreateTrueColor($this->iNewWidth,
                                                $this->iNewHeight);
                // 画像の変換
                ImageCopyResampled($des_img, $src_img, 0, 0, 0, 0,
                         $this->iNewWidth, $this->iNewHeight,
                         $this->iOrgWidth, $this->iOrgHeight);
                // 画像の描画
                header("Content-type: ".$this->sMimeType);
                ImageJpeg($des_img, "", $this->iQuality);
                break;

            case FMT_PNG:
                $src_img = ImageCreateFromPng($this->sFilename);
                $des_img = ImageCreateTrueColor($this->iNewWidth,
                                                $this->iNewHeight);
                // 画像の変換
                ImageCopyResampled($des_img, $src_img, 0, 0, 0, 0,
                         $this->iNewWidth, $this->iNewHeight,
                         $this->iOrgWidth, $this->iOrgHeight);
                // 画像の描画
                header("Content-type: ".$this->sMimeType);
                ImagePng($des_img);
                break;

            default:
                return;
        }
        ImageDestroy($src_img);
        ImageDestroy($des_img);
    }
}

// インスタンス作成
$req = new ViewImage();
$req->getImageInfo();
$req->setNewSize();
$req->showImage();

?>