PHPの関数には、Exif情報を読み出すexif拡張モジュールがあって、exif_read_data()関数を使うと読み出せるのだが、exifサポートを有効化するには、PHPを --enable-exif でコンパイルしなければならない。なので、PHPをコンパイルできないレンタルサーバ等で、exifサポートが有効になっていない環境では使えない。
Exifパーサをイチから作るのはタイヘンだが、GPLライセンスでThe PHP JPEG Metadata Toolkitというのがあったのでありがたく拝借。これを使えばexif_read_data()がなくてもExifが読み出せる。
ソースのzipをダウンロードして、使うサーバで以下のファイルを配置する。
EXIF.phpMakernotes/以下は、EXIF_Makernote.php の中で動的に読み込まれているので、不要なものは配置しなくて良いだろう。また、この読込ルーチンで、opendir() に失敗するとreaddir()がNULLを返してループすることがあるので、ちょっと変更。
EXIF_Makernote.php
EXIF_Tags.php
IPTC.php
JFIF.php
JPEG.php
Photoshop_IRB.php
PictureInfo.php
PIM.php
pjmt_utils.php
Unicode.php
XML.php
XMP.php
Makernotes/
agfa.php
canon.php
casio.php
epson.php
fujifilm.php
konica_minolta.php
kyocera.php
nikon.php
olympus.php
panasonic.php
Pentax.php
ricoh.php
sony.php
EXIF_Makernote.php:
// Open the directory
$dir_hnd = @opendir ( $dir );
// Cycle through each of the files in the Makernotes directory
while ( $dir_hnd && ( $file = readdir( $dir_hnd ) ) !== false )
{
:
略
:
}
// close the directory
if( $dir_hnd ) closedir( $dir_hnd );
そして、Exifを読み込む側で、
include_once 'EXIF.php';実行結果
// $filename = 読み込むjpeg等のファイルのパス
$exif = get_EXIF_JPEG( $filename );
[0]=>
array(10) {
["Tags Name"]=>
string(4) "TIFF"
["Tiff Offset"]=>
int(12)
[271]=>
array(9) {
["Tag Number"]=>
int(271)
["Tag Name"]=>
string(19) "Make (Manufacturer)"
["Tag Description"]=>
string(0) ""
["Data Type"]=>
int(2)
:
略
という具合で、Exifが取れる。構造は、タグ番号 => array() で、タグ番号の意味は "Tags Name" を見れば分かるが、この対応付けは EXIF_Tags.php に書かれているので、この番号をキーに配列を探せば良い。たとえばGPS位置情報タグは、$exif[0][34853] あたり。このままでは使いにくいので、exif_read_data()のように平たい配列に変換するため、
function Interpret_EXIF_to_Array($exif, &$ret_array, $tagname_num = true)とりあえずざっくりと簡単にこんな関数を用意。$tagname_num にtrueを渡すと配列キーがタグの番号で、falseを渡すと文字列で返す。実行結果
{
if( !is_array($exif) || count( $exif ) <= 0 ) return false;
$i = 0;
while( array_key_exists($i, $exif) )
{
interpret_IFD_array($exif[$i], $ret_array, $tagname_num);
$i++;
}
return true;
}
function interpret_IFD_array($ifd, &$ret_array, $tagname_num)
{
if( !is_array($ifd) ) return false;
foreach( $ifd as $tagid => $tag )
{
if ( !is_numeric($tagid) || !$tag['Decoded'] ) continue;
$tagname = $tagname_num ? $tagid : $tag['Tag Name'];
switch($tag['Type']){
case "SubIFD":
$ret_array[ $tagname ] = array();
foreach ( $tag['Data'] as $subIFD )
{
interpret_IFD_array( $subIFD, $ret_array[ $tagname ], $tagname_num );
}
break;
case "Maker Note":
case "IPTC":
case "XMP":
case "IRB":
break;
case "Numeric":
default:
$ret_array[ $tagname ] = $tag['Text Value'];
break;
}
}
return true;
}
// $filename = 読み込むjpeg等のファイルのパスこれで、
// $ret に結果が入る
Interpret_EXIF_to_Array( get_EXIF_JPEG( $filename ), $ret);
array(10) {大体、exif_read_data()と似たデータが取れるようになった。
[271]=>
string(3) "hogehogoe"
[272]=>
string(5) "ahoaho"
[282]=>
string(39) "72/1 (72) pixels per 'Resolution Unit' "
[283]=>
string(39) "72/1 (72) pixels per 'Resolution Unit' "
[296]=>
string(6) "Inches"
[531]=>
:
略
▼レンタルサーバー・VPS比較表を見る▼