ケータイ端末別に画像画面サイズを変換するには

By ookura - 08/10/09 - このエントリをはてなブックマークに追加このエントリをYahoo!ブックマークに追加このエントリをdel.icio.usに追加このエントリをFC2ブックマークに追加

前回は画像の形式変換について説明しましたが、今回は画像サイズの変更方法について。
→参照:「ケータイで表示できる画像形式に変換するには」
 
 
以前説明しました通り、携帯では画像のサイズが画面サイズより大きい場合に機種によって表示できない場合があります。
そのため、画面サイズに応じて最適なサイズで表示させる必要があります。
→参照:「ケータイで表示できる画像のブラウザ画面サイズ」
 
※確認した端末では端末より大きい画像を表示すると以下のように表示されました。
・横サイズが大きい場合は画面横サイズに合わせて自動的にリサイズ
・縦サイズが大きい場合はリサイズせずスクロールで表示
 
 


機種別のサイズ取得

機種の情報としては以下のデータが必要になります。

・画面幅・高さ(px)
・各画像形式(JPEG・GIF・PNG)対応状況

 
 
この情報をCSVデータとしてあらかじめ用意しておき、一行ずつ読み込んでマッチした機種の情報を取得します。
→参照:「ケータイで表示できる画像形式に変換するには」
 
PCでアクセスした場合などマッチしなかった場合は240×320で全形式表示可、としています。
 
 
今回はこのような項目で機種情報を持たせています。

キャリア,機種名,ユーザーエージェント,画面幅,画面高さ,JPEG対応,GIF対応,PNG対応

※JPEG対応,GIF対応,PNG対応は1→対応 0→非対応
 
 
 データの例を以下に示します。
DeviceData.csv(一部抜粋)

softbank,905SH,Vodafone/1.0/V905SH,240,400,1,1,1
softbank,904T,Vodafone/1.0/V904T,240,320,1,1,1
softbank,703N,Vodafone/1.0/V703N,240,269,1,1,1
au,A1014ST,UP.Browser/3.04-ST14,120,108,1,0,1
au,A1011ST,UP.Browser/3.04-ST13,120,126,1,0,1
softbank,921T,SoftBank/1.0/921T,234,339,1,1,1
softbank,921SH,SoftBank/1.0/921SH,468,754,1,1,1
willcom,WX331K,Mozilla/3.0(WILLCOM;KYOCERA/WX331K,235,245,1,1,1
willcom,AH-K3002V,Mozilla/3.0(DDIPOCKET;KYOCERA/AH-K3002V,237,241,1,1,1
softbank,702sMO,MOT-C980,176,182,1,1,1
au,W63T,KDDI-TS3K,234,267,1,1,1
au,W44K,KDDI-KC38,232,237,1,1,1
softbank,V801SH,J-PHONE/5.0/V801SH,240,260,1,0,1
softbank,J-T51,J-PHONE/4.2/J-T51,144,144,1,0,1
softbank,V403SH,J-PHONE/3.0/V403SH,240,260,1,0,1
softbank,J-DN03,J-PHONE/3.0/J-DN03,120,130,1,0,1
docomo,SH705iII,DoCoMo/2.0 SH705i2,240,320,1,1,0
docomo,SH705i,DoCoMo/2.0 SH705i,240,320,1,1,0
docomo,P704iμ,DoCoMo/2.0 P704imyu,240,270,1,1,0
docomo,P704i,DoCoMo/2.0 P704i,240,270,1,1,0
docomo,SO503iS,DoCoMo/1.0/SO503iS,120,113,0,1,0
docomo,SO503i,DoCoMo/1.0/SO503i,120,113,0,1,0

 
 


出力縦横サイズの計算

正しく計算しないと縦横比が変わって画像がゆがんでしまったり、縦長、横長の画像で画面サイズをオーバーしてしまったりします。
今回は以下のような手順で計算しています。
 
1.出力サイズの初期値として元画像サイズを設定
 
2.元画像幅が端末幅を超える場合は横幅調整

出力幅 = 端末幅
出力高さ = 元画像高さ × (端末幅の元画像幅に対する割合)

 
3.出力高さが端末高さを超える場合は高さ調整

出力幅 = 出力幅 × (端末高さの元画像高さに対する割合)
出力高さ = 端末高さ

 
4.出力サイズの小数点を切り上げ
 
 
例えば画面サイズが240×320の場合は以下のような結果になります。
 

ケース 元画像幅 元画像高さ 出力画像幅 出力画像高さ
縦横ともに大きい場合 400px 400px 240px 240px
横のみ大きい場合 400px 100px 240px 60px
縦のみ大きい場合 100px 400px 80px 320px
縦横ともに小さい場合 100px 100px 100px 100px

 
 


画像のリサイズ

画像のリサイズを行う場合、以下の手順で行います。
 
元画像を読み込む
imagecreatefromjpeg
imagecreatefromgif
imagecreatefrompng

出力したい画像のサイズで新規イメージを作成する。
imagecreatetruecolor

新規イメージに出力したい画像をサイズ指定してコピー
imagecopyresampled

新規イメージを出力
imagejpeg
imagegif
imagepng
 
 
リサイズが不要な場合は処理を省略します。
 
 


PHPソース例

実際のソースは以下の通りです。
 
sample1.php

<?php
/* 
 * 端末別に画像縦横サイズを変換して出力するサンプル
 */

// 画像ファイルパス情報
$imgFile = basename($_GET['file']);

// ファイルの存在チェック
if ((!file_exists($imgFile)) || ($imgFile == '')) {
    die('Error : File not exists.');
}

$userAgent = $_SERVER['HTTP_USER_AGENT'];
$deviceList = file("DeviceData.csv");
foreach ($deviceList as $key => $value) {
    list($carrier, $name, $agent, $deviceWidth, $deviceHeight, 
        $jpegFlg, $gifFlg, $pngFlg) = explode(',', $value);
    if (ereg($agent, $userAgent)) {
        $pngFlg = trim($pngFlg);
        $match = true;
        break;
    } else {
        $match = false;
    }
}

// マッチしなかった場合の処理
if (!$match) {
    $carrier = 'PC';
    $name = '';
    $agent = '';
    $deviceWidth  = 240;
    $deviceHeight = 320;
    $jpegFlg = 1;
    $gifFlg = 1;
    $pngFlg = 1;
}

// 画像ファイルの幅,高さ,mimetypeを確認
list($imageWidth, $imageHeight, $imageType) = getimagesize($imgFile);

// 無変換の場合は画像サイズを出力サイズとする
$outWidth  = $imageWidth;
$outHeight = $imageHeight;

// 元画像幅が端末幅を超える場合は横幅調整
if (($deviceWidth !== 0) && ($imageWidth > $deviceWidth)) {
    // 出力幅 = 端末幅
    $outWidth  = $deviceWidth;
    // 出力高さ = 元画像高さ × (端末幅の元画像幅に対する割合)
    $outHeight = $imageHeight * ($deviceWidth / $imageWidth);
}

// 出力高さが端末高さを超える場合は縦幅調整
if (($deviceHeight !== 0) && ($outHeight > $deviceHeight)) {
    // 出力幅 = 出力幅 × (端末高さの元画像高さに対する割合)
    $outWidth  = $outWidth * ($deviceHeight / $outHeight);
    // 出力高さ = 端末高さ
    $outHeight = $deviceHeight;
}

// 切り上げ
$outWidth  = ceil($outWidth);
$outHeight  = ceil($outHeight);

// 出力形式を決定
$outExt = 'jpg';
if ($jpegFlg != 1) {
    if ($gifFlg != 1) {
        $outExt = 'png';
    } else {
        $outExt = 'gif';
    }
}


// 拡張子を判別して画像情報を取得
$extention = pathinfo($imgFile, PATHINFO_EXTENSION);
$extention = strtolower($extention);

$mimeType = image_type_to_mime_type($imageType);

switch ($extention) {
case 'jpg' :
case 'jpeg' :
    // mimetypeが拡張子と異なる場合はエラー終了
    if ($mimeType != 'image/jpeg') {
        die('Error : This file is not jpeg file.');
    }
    $imageID = imagecreatefromjpeg($imgFile);
    break;
case 'gif' :
    if ($mimeType != 'image/gif') {
        die('Error : This file is not gif file.');
    }
    $imageID = imagecreatefromgif($imgFile);
    break;
case 'png' :
    if ($mimeType != 'image/png') {
        die('Error : This file is not png file.');
    }
    $imageID = imagecreatefrompng($imgFile);
    break;
default ;
    die('Error : This file cannot convert.');
    break;
}

// 必要であればリサイズ
if (($outWidth != $imageWidth) || ($outHeight != $imageHeight)) {
    // 新規イメージを作成
    $outImg = imagecreatetruecolor($outWidth, $outHeight);
    // リサイズしてコピー
    imagecopyresampled($outImg, $imageID, 0, 0, 0, 0, 
        $outWidth, $outHeight, $imageWidth, $imageHeight);
} else {
    $outImg = $imageID;
}

// ヘッダ情報として出力したい形式のMIME情報を出力
// 出力したい形式で画像情報を出力
switch ($outExt) {
case 'jpg' :
    header("Content-Type: image/jpeg");
    imagejpeg($outImg);
    break;
case 'gif' :
    header("Content-Type: image/gif");
    imagegif($outImg);
    break;
case 'png' :
    header("Content-Type: image/png");
    imagepng($outImg);
    break;
default ;
    exit;
    break;

}
?>

 


実行例

実行例はこちらからご確認下さい。

URLをメールで送る
http://ookura.tanikaze.com/Sample/post678/