前回の記事「モバゲーのような携帯サイトを作るための12のTips」が予想以上の大反響で少々びっくりしてます。はてブの数とか半端ないです。こんなブックマークが付く記事を書いたことがありません。笑
いといろとコメントくださった方ありがとうございます。
おかげさまで、この記事以来、怒濤のように仕事が舞い込んできており、
多忙の毎日を送っています。
さて、今回は前回の記事のコメントでいただいた、
ソフトバンクのVGA端末でのサイト内画像の出力に関するお話です。
前回の記事で、ソフトバンクの高解像度(横240ピクセル以上)VGA端末では、ロゴなどの画像を他のキャリアに合わせて横240ピクセルで作成した画像を表示すると、高解像度のまま小さく表示されてしまう(けっこうかっこ悪い…)という問題がでてきてしまうという点について触れました。
ちなみに、ソフトバンク以外のキャリアの端末では高解像端末でも、画像の自動拡大縮小機能がブラウザについているので、画面ぴったりに表示されます。ちょうど以下のような感じ。
確かにソフトバンクの端末は挙動としては最も正しいのですが、このサイトの方針のように3キャリア対応で作成するとなると、やはりこの問題は無視できません。画像のwidth属性を100%で指定すれば、とりあえず画面いっぱいに表示されますが、これだと画像が拡大され粗が目立ってしまってかっこ悪い。
そこで、今回は他とは違ったアプローチでこの問題を簡易的に解決する方法を考えました。
結論から言うと、今回も絵文字のときと同じようにスクリプトに頼るのですが、
今回もコーダー視点で作成し、導入の敷居は低く設定してます。このブログのターゲットやサイト規模とかも考えて、MobaSiFのようなフレームワークを導入するほどじゃないんだけど…って人結構多いですからね。
今回のスクリプトの設計はというと、
・1枚のオリジナル画像(横480ピクセル×縦自由のJPG)を3キャリアで共有する。
・ソフトバンク端末のVGA機種(正確には横400ピクセル以上の端末)のみ、オリジナル画像をそのまま表示する。
・その他のキャリアは画像をサーバー側で縮小(GDを利用)し、横240ピクセルに縮小した画像を出力する。
・HTMLからの読み出しはSSIを使用する。
ただこれだけです。本来は、端末から機種名を読み出し(画像サイズを端末から読み出せないキャリアもあるため)、画像サイズのデータベースと照らし合わせ、適切な画像サイズに加工してから最適なサイズで出力する。といったスクリプトが一番良いのですが、そこまで対応させる労力はありません。すみません。
ではスクリプトです。
サンプルURL:http://www.dspt.net/data/imagetrans/
ソース:http://www.dspt.net/data/imagetrans/trans.txt
<?php
//┌─────────────────────────────────
//│ [ IMG TRANS Ver1.0]
//│ trans.php - 2008/08/13
//│ Copyright (C) DSPT.NET
//│ http://www.dspt.net/
//└─────────────────────────────────
/********************** 初期設定 ***********************/
//リサイズ後の画像保存先ディレクトリ(相対パス)
$img_dir = 'images/';
/********************** 以下からは改変しないほうが無難 ***********************/
//対象画像のファイル名を取得
$img_file = $_GET["file"];
//エンコード変換(オプション)
function encode($data) {
$data = mb_convert_encoding($data, "SJIS", "auto");
return $data;
}
//携帯UA取得
$agent = $_SERVER["HTTP_USER_AGENT"];
//携帯端末のユーザエージェントを判定
function mobile($data){
if(preg_match("/^DoCoMo\/[12]\.0/i", $data))
{
return "i";// i-mode
}
elseif(preg_match("/^(J\-PHONE|Vodafone|MOT\-[CV]980|SoftBank)\//i", $data))
{
return "s";// softbank
}
elseif(preg_match("/^KDDI\-/i", $data) || preg_match("/UP\.Browser/i", $data))
{
return "e";// ezweb
}
elseif(preg_match("/^PDXGW/i", $data) || preg_match("/(DDIPOCKET|WILLCOM);/i", $data))
{
return "w";// willcom
}
elseif(preg_match("/^L\-mode/i", $data))
{
return "l";// l-mode
}
else {
return "p";// pc
}
}
//横240ピクセル用の画像を作成(GD利用)
$img_240 = ImageCreateFromJPEG($img_file);
$width = ImageSx($img_240);
$height = ImageSy($img_240);
$resize_width = $width/2;
$resize_height = $height/2;
$out = ImageCreateTrueColor($resize_width, $resize_height);
$base = basename ($img_file,".jpg");
$img_filename = $img_dir.$base."_240.jpg";
ImageCopyResampled($out, $img_240, 0, 0, 0, 0, $resize_width, $resize_height, $width, $height);
ImageJPEG($out, $img_filename, 100);
//パス取得
$path = dirname($HTTP_SERVER_VARS['PHP_SELF'])."/".$img_filename;
$path_s = dirname($HTTP_SERVER_VARS['PHP_SELF'])."/".$img_file;
//ソフトバンク携帯の場合
if (mobile($agent) == "s") {
//ソフトバンク携帯の画面サイズ取得
$softbank_display = $_SERVER["HTTP_X_JPHONE_DISPLAY"];
$display = array();
$display = explode("*", $softbank_display);
//縦横それぞれ取得
$softbank_display_width = $display[0];
$softbank_display_height = $display[1];
}
//携帯キャリアに合わせて画像タグを出力
function img_tag() {
global $agent,$img_file,$path,$path_s,$width,$height,
$resize_width,$resize_height,$softbank_display_width;
switch(mobile($agent)){
case "i";
$put = "<img src=\"".$path."\" width=\"".$resize_width."\" height=\"".$resize_height."\" alt=\" \" /><br />";
break;
case "e";
$put = "<img src=\"".$path."\" width=\"".$resize_width."\" height=\"".$resize_height."\" alt=\" \" /><br />";
break;
case "s";
if ($softbank_display_width > 400) {
$put = "<img src=\"".$path_s."\" width=\"".$width."\" height=\"".$height."\" alt=\" \" /><br />";
} else {
$put = "<img src=\"".$path."\" width=\"".$resize_width."\" height=\"".$resize_height."\" alt=\" \" /><br />";
}
break;
case "p";
$put = "<img src=\"".$path."\" width=\"".$resize_width."\" height=\"".$resize_height."\" alt=\" \" /><br />";
break;
}
echo $put;
}
//処理
img_tag();
?>
このスクリプトの仕組みは、まず、対象となる画像を以下のようにHTML側でSSIで指定し、本PHPを読み出します。
<!--#include virtual="/data/imagetrans/trans.php?file=test.jpg"-->
赤字の部分で読み出したい画像のファイル名を「file=ファイル名」で指定します。
オリジナルとなる画像(test.jpg)はPHPスクリプトと同じディレクトリに置く必要があります。
今回もPHPの場所はトップディレクトリから相対パスで指定します。
スクリプトはSSIで指定された画像を読み出し、とりあえず縮小版(横240ピクセル)をGDを使って作成し、スクリプト冒頭で指定したフォルダ(実行権限を707等にすること)に「_240」をつけて保存(test_240.jpg)します。
例によって、SSIをHTMLで読み出してやらなければなりませんから、.htaccess等に
以下の一文を追加し、PHPと同じディレクトリに置きます。
AddHandler server-parsed html
GDについては、サーバー側にインストールされている必要がありますが、たぶんたいていは大丈夫かと。不安であれは<?php phpinfo(); ?>でGDの項を見て「enable」になっていればOKかと思います。XREAサーバーで動作確認しました。
後は、携帯のユーザエージェントを判断して、ソフトバンクVGA端末以外は縮小画像を表示するHTMLタグを出力し、ソフトバンク端末のみ「HTTP_X_JPHONE_DISPLAY」というHTTPヘッダーから画面サイズを取得し、横が400以上の端末はオリジナル画像を表示するHTMLタグを出力する仕組みです。
このスクリプトはとりあえず付け焼き刃的なものなので、いったん縮小画像を作ってからも
毎回GDを起動してしまったりと若干効率が悪いです。この辺はファイルの存在を確認する一文を入れたほうがいいかも。時期を見計らってまた更新します。
本日は以上です。
SSIではなくPHPで
たぶん、雰囲気からお忙しそうでお答えいただくのは難しいと思いますが、是非ご回答をお願いします。
SSIでPHPを呼び出すように作られていますが、PHPで呼び出す方法はありますか? 画像の変換だけを見た場合はSSIでもPHPでもどちらでも良さそうですが、他にも利用を考えるとPHPの方が他のPHPと組み合わせが良いもので・・・そういう人多いと思います。 絵文字変換もPHP版とSSI版が出ていますよね。同じ発想です。 宜しくお願い申し上げます。 ppp | URL | 2009/11/20/Fri 11:02 [EDIT]
http://www.dspt.net/data/imagetrans/trans.php?file=test000.jpg
エラー回避が足りないんじゃないの? あと作成済みの画像があったらキャッシュを読んだりしないと非効率的だと思われる
PHP5の場合の件
何度もすいません!
素人ながら調べたところ、$HTTP_SERVER_VARSこの部分を$_SERVERに変更したら表示されました! もしかして、すごい危険な?変更かもしれないので、適切な処置で無い場合は、お手数を掛けますが、このコメントを削除してください! 本当に、すごく貴重な情報をたくさん有難うございます! 今後も、情報期待しております! chiaki | URL | 2008/11/26/Wed 19:11 [EDIT]
PHP5の場合
すごく重宝させてもらってます!
ところで、このスクリプトですが、PHP5の場合、画像が×で表示されません。 imagesの中には縮小された画像が入っております。 なにか対応策はないでしょうか!? まったくの素人ですので、PHPが解明できません<m(__)m> お時間が空いているときにご教授頂ければ有りがたいです。 よろしくお願いします chiaki | URL | 2008/11/26/Wed 16:52 [EDIT]
ゆきさん
書き込みありがとうございます。 本スクリプトで対象としてるのは、JPEG画像でかつ、 拡張子が「*.jpg」となっているものに限ります。 したがって、test.gifだとGIF画像なので、おそらくファイル名設定の部分や GDのファイル処理あたりでエラーになってしまっているのだと思います。 とりあえず適当なJPG画像を用意して試してみてください。 shiba | URL | 2008/09/02/Tue 15:48 [EDIT]
はじめまして、こんにちは。携帯サイトを作るにあたりすごく参考にさせていただいています。
今回こちらのスクリプトをお借りしてみたのですが、上手くいかず躓いてしまいました…。お忙しいところ申し訳ありませんが、もし何か分かればヒントなどいただけませんでしょうか。 <img src="/image/_240.jpg" width="0" height="0" alt=" " /> (imgフォルダ内に_240.jpgは存在なし) GDはenabledでバージョンは2.0.28です。 関連するフォルダはすべて777にしています。 ゆき | URL | 2008/09/02/Tue 14:50 [EDIT]
Re : 今回もとても興味深い記事でした(^^)
タマミさん
コメントありがとうございます。 動作確認は必ず実機で行うようにしています。 エミュレーターでは確認できる範囲に限界があって、実機とは異なる挙動をする場合がありますので。 全キャリア持ってはいませんが、ある程度エミュレータで確認しておいて、 後は人脈をフルに使って、友人の携帯を借りたりして確認してます。 shiba | URL | 2008/08/26/Tue 16:36 [EDIT]
今回もとても興味深い記事でした(^^)
shibaさんは、高度な携帯サイトをつくられた時には、どうやって動作確認をするのですか?
私はデザイン・レイアウトはシュミレーターで確認しているのですが、PHPフォームなどは確認ができなくていつも困っています。 全キャリアを購入させてくれるような仕事ができるようになりたい・・・ タマミ | URL | 2008/08/26/Tue 16:15 [EDIT]
|