以前、画像サイズの変更方法について説明しましたが、今回は画面サイズとの比率に応じた画像サイズの変更方法について。
→参照:「ケータイ端末別に画像画面サイズを変換するには」
固定サイズに縮小した場合の問題点
ケータイサイトを制作していると、例えば商品画像のサムネイル表示をする場合などで画面サイズより小さく画像を表示したい場合があります。
しかし、固定サイズで出力していると、以下の問題点がでてきます。
- 画面サイズの小さい機種では縦横サイズオーバーになってしまうことがある。
- 画面の割合に対して非常に大きいサイズで表示されてしまう。
- 画面サイズの大きい機種では逆にものすごく小さく表示されてしまう。
- 縦横比が極端な画像の場合画面サイズをオーバーしてしまう。
この問題点を解決するには、固定サイズではなく、画面サイズに対して一定の割合で縮小して表示するようにします。
画面サイズに対する割合を指定して縮小するには
まず、画面サイズに対する割合を制限サイズとして考えます。
そして制限サイズに合わせて縮小するように計算すると、うまく縮小することができます。
計算方法
1.出力サイズの初期値として元画像サイズを設定
2.比率が指定されていれば端末幅・端末高さに比率をかけて制限幅・制限高さを計算する
3.元画像幅が制限幅を超える場合は横幅調整
出力幅 = 制限幅 出力高さ = 元画像高さ × (制限幅の元画像幅に対する割合)
4.出力高さが制限高さを超える場合は高さ調整
出力幅 = 出力幅 × (制限高さの元画像高さに対する割合) 出力高さ = 制限高さ
5.出力サイズの小数点を切り上げ
例えば画面サイズが240×320の場合は以下のような結果になります。
| 指定比率 | 元画像の状態 | 元画像幅 | 元画像高さ | → | 出力画像幅 | 出力画像高さ |
|---|---|---|---|---|---|---|
| 幅を50%に 縮小する場合 |
縦横ともに大きい場合 | 400px | 400px | → | 120px | 120px |
| 横のみ大きい場合 | 400px | 100px | → | 120px | 30px | |
| 縦のみ大きい場合 | 100px | 400px | → | 80px | 320px | |
| 縦横ともに小さい場合 | 100px | 100px | → | 100px | 100px | |
| 高さを50%に 縮小する場合 |
縦横ともに大きい場合 | 400px | 400px | → | 160px | 160px |
| 横のみ大きい場合 | 400px | 100px | → | 240px | 60px | |
| 縦のみ大きい場合 | 100px | 400px | → | 40px | 160px | |
| 縦横ともに小さい場合 | 100px | 100px | → | 100px | 100px | |
| 幅を50%に、 高さを50%に 縮小する場合 |
縦横ともに大きい場合 | 400px | 400px | → | 120px | 120px |
| 横のみ大きい場合 | 400px | 100px | → | 120px | 30px | |
| 縦のみ大きい場合 | 100px | 400px | → | 40px | 160px | |
| 縦横ともに小さい場合 | 100px | 100px | → | 100px | 100px |
PHPソース例
実際のソースは以下の通りです。
sample1.php
<?php
/*
* 端末画面サイズに対する比率で画像を縮小して出力するサンプル
*/
// 画像ファイルパス情報
$imgFile = basename($_GET['file']);
// ファイルの存在チェック
if ((!file_exists($imgFile)) || ($imgFile == '')) {
die('Error : File not exists.');
}
// 比率(%)指定
$widthPercentage = intval($_GET['wp']);
$heightPercentage = intval($_GET['hp']);
if (($widthPercentage >= 100) || ($heightPercentage >= 100)) {
die('Error : Input value is out of range.');
}
$widthRatio = $widthPercentage / 100;
$heightRatio = $heightPercentage / 100;
$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 (strpos($userAgent, $agent) === 0) {
$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 ($widthRatio > 0) {
// 制限幅 = 端末幅 × 横比率
$limitWidth = $deviceWidth * $widthRatio;
} else {
$limitWidth = $deviceWidth;
}
if ($heightRatio > 0) {
// 制限高さ = 端末高さ × 縦比率
$limitHeight = $deviceHeight * $heightRatio;
} else {
$limitHeight = $deviceHeight;
}
// 元画像幅が制限幅を超える場合は横幅調整
if (($limitWidth !== 0) && ($imageWidth > $limitWidth)) {
$outWidth = $limitWidth;
// 出力高さ = 元画像高さ × (制限幅の元画像幅に対する割合)
$outHeight = $imageHeight * ($limitWidth / $imageWidth);
}
// 出力高さが制限高さを超える場合は縦幅調整
if (($limitHeight !== 0) && ($outHeight > $limitHeight)) {
// 出力幅 = 出力幅 × (制限高さの元画像高さに対する割合)
$outWidth = $outWidth * ($limitHeight / $outHeight);
// 出力高さ = 制限高さ
$outHeight = $limitHeight;
}
// 切り上げ
$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;
}
?>
使用例
パラメータは以下のように渡します。
| パラメータ名 | 概要 | 備考 |
|---|---|---|
| file | 画像ファイル名 | ※必須 |
| wp | 幅比率(%) | ※任意 |
| hp | 高さ比率(%) | ※任意 |
画像取得URL例:
sample1.php?file=photo_400×400.jpg&wp=50&hp=50
実行例
実行例はこちらからご確認下さい。
→URLをメールで送る
http://ookura.tanikaze.com/Sample/post906/







