PHPでExif情報を表示する

(1/1)
デジカメで撮影されたJPEG画像には、撮影日時に加え、絞り、シャッター速度、デジカメの機種名、メーカー名など、さまざまな情報が Exif と呼ばれるタグ情報となって埋め込まれている。最近の GPS付携帯デジカメでは、緯度・経度情報まで記録されている。

(2022年2月19日)PHP8対応,全面改訂

目次

準備

PHPには、Exif情報を取得する  exif_read_data  関数が用意されている。この関数を利用するのにGDライブラリは不要だが、--enable-exif を enable にして PHPをコンパイルする必要がある。配布されている Windows バイナリの場合、extension に php_exif.dll を指定してやるだけで利用できるようになる。ただし、かならず php_mbstring.dll の後に読み込む必要がある。つまり、php.ini の定義は、かならず下記の順番にしておく必要がある。
extension=php_mbstring.dll
extension=php_exif.dll
では、任意の画像ファイルの Exif 情報を表示するPHPプログラムを紹介する。

サンプル・プログラムの実行例

PHPでExif情報を表示する

サンプル・プログラム

圧縮ファイルの内容
sprintexif.phpサンプル・プログラム本体。

解説:Exif情報を配列に格納する

 187: /**
 188:  * Exif情報を配列に格納する(下請け関数)
 189:  * @param  String $fname 画像ファイル名
 190:  * @param  Array  $exif  Exif情報を格納する配列
 191:  * @return    0:正常に表示した
 192:  *          (-1): ファイルが存在しない
 193:  *          (-2): JPEG/TIFF以外の形式
 194:  *          (-3): Exif情報がない
 195: */
 196: function _getexif($fname, &$exif) {
 197:     //ファイルの存在チェック
 198:     if (fopen($fname, 'rb') == FALSE)   return (-1);
 199: 
 200:     //JPEG/TIFFの型チェック
 201:     switch (exif_imagetype($fname)) {
 202:         case IMAGETYPE_JPEG:
 203:         case IMAGETYPE_TIFF_II:
 204:         case IMAGETYPE_TIFF_MM:
 205:             break;
 206:         default:
 207:             return (-2);
 208:     }
 209: 
 210:     //Exif情報を配列へ
 211:     if (($cls = exif_read_data($fname, 'EXIF')) == FALSE)   return (-3);
 212:     foreach ($cls as $key=>$sect) {
 213:         if (is_array($sect) == FALSE) {
 214:             $exif[$key] = $sect;
 215:         } else {
 216:             foreach($sect as $name=>$val)   $exif[$key . '.' . $name] = $val;
 217:         }
 218:     }
 219:     return 0;
 220: }

このプログラムの主役は、ユーザー定義関数 _getexif である。引数は、ファイル名(URLも可能)と、Exif 情報を格納するための配列変数の2つ。

まず、ファイルが存在するかどうか調べる。
次に、そのファイルがJPEGかTIFFであるかどうか調べる。このような目的のために、PHPには  exif_imagetype  という関数が用意されている。
これらをクリアして、はじめて  exif_read_data  関数を使って Exif 情報を読み出す。
なお、Exif 情報がない場合は、  exif_read_data  関数は FALSE を返すので、このエラーもキャッチしておく必要がある。

Exif情報はオブジェクト構造をしている。そこで、配列の添え字にタグ名、配列の中身として値を格納することにする。
これを実現するために、二段構えの foreach 構文で情報を配列へ展開している。
なお、タグ名の一部はデジカメ固有の文字列なので注意が必要だ。詳細はこちら

 222: /**
 223:  * Exif情報を配列に格納する
 224:  * @param  string $url   画像ファイルURL
 225:  * @param  string $fname 画像ファイル(ローカル)
 226:  *                $url, $fnameいずれか一方を渡す
 227:  * @param  array  $exif    Exif情報を格納する配列
 228:  * @param  string $errmsg  エラーメッセージ
 229:  * @return    なし
 230: */
 231: function getexif($url, $fname, &$exif, &$errmsg) {
 232:     //Exif情報の取得 - ネット上
 233:     if ($url !'') {
 234:         $fname = $url;
 235:         $arr   = array();
 236:         $ret   = _getexif($fname, $exif);
 237:     //Exif情報の取得 - ローカルファイル
 238:     } else if ($fname !'') {
 239:         $arr = array();
 240:         $ret = _getexif($fname, $exif);
 241:     }
 242: 
 243:     //結果判断
 244:     $errmsg = '';
 245:     switch ($ret) {
 246:         case 0:
 247:             $errmsg = '';
 248:             break;
 249:         case (-1):
 250:             $errmsg = 'ファイルが存在しません';
 251:             break;
 252:         case (-2):
 253:             $errmsg = 'ファイル形式がJPEG/TIFF以外です';
 254:             break;
 255:         case (-3):
 256:             $errmsg = 'Exif情報がありません';
 257:             break;
 258:         case (-4):
 259:             $errmsg = 'ファイルサイズが大きすぎます';
 260:             break;
 261:         default:
 262:             $errmsg = 'ファイル名またはURLを入力してください';
 263:             break;
 264:     }
 265: }

ユーザー定義関数 getexif は、画像ファイルURL、画像ファイル(ローカル)のいずれか一方を引数とし、先ほどのユーザー定義関数 _getexif を呼び出し、Exif情報を格納した配列とエラー・メッセージを返す。

応用

Exif情報にある撮影年月日を使って、デジカメのファイル名を整理できる。この手のフリーソフトは何種類か出ているが、PHPでも同じことができる。
はてなフォトライフでは、Exifから取得した位置情報をはてなマップへ展開する機能を持っている。
はてなマップはGoogle Mapの機能を使っており、PHP でも同様のアプリケーションは実現できるだろう。
(この項おわり)
header