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情報を配列に格納する

0187: /**
0188:  * Exif情報を配列に格納する(下請け関数)
0189:  * @param   String $fname 画像ファイル名
0190:  * @param   Array  $exif  Exif情報を格納する配列
0191:  * @return  0:正常に表示した
0192:  *          (-1): ファイルが存在しない
0193:  *          (-2): JPEG/TIFF以外の形式
0194:  *          (-3): Exif情報がない
0195: */
0196: function _getexif($fname, &$exif) {
0197:     //ファイルの存在チェック
0198:     if (fopen($fname, 'rb') == FALSE)  return (-1);
0199: 
0200:     //JPEG/TIFFの型チェック
0201:     switch (exif_imagetype($fname)) {
0202:         case IMAGETYPE_JPEG:
0203:         case IMAGETYPE_TIFF_II:
0204:         case IMAGETYPE_TIFF_MM:
0205:             break;
0206:         default:
0207:             return (-2);
0208:     }
0209: 
0210:     //Exif情報を配列へ
0211:     if (($cls = exif_read_data($fname, 'EXIF')) == FALSE)  return (-3);
0212:     foreach ($cls as $key=>$sect) {
0213:         if (is_array($sect) == FALSE) {
0214:             $exif[$key] = $sect;
0215:         } else {
0216:             foreach($sect as $name=>$val)   $exif[$key . '.' . $name] = $val;
0217:         }
0218:     }
0219:     return 0;
0220: }

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

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

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

0187: /**
0188:  * Exif情報を配列に格納する(下請け関数)
0189:  * @param   String $fname 画像ファイル名
0190:  * @param   Array  $exif  Exif情報を格納する配列
0191:  * @return  0:正常に表示した
0192:  *          (-1): ファイルが存在しない
0193:  *          (-2): JPEG/TIFF以外の形式
0194:  *          (-3): Exif情報がない
0195: */
0196: function _getexif($fname, &$exif) {
0197:     //ファイルの存在チェック
0198:     if (fopen($fname, 'rb') == FALSE)  return (-1);
0199: 
0200:     //JPEG/TIFFの型チェック
0201:     switch (exif_imagetype($fname)) {
0202:         case IMAGETYPE_JPEG:
0203:         case IMAGETYPE_TIFF_II:
0204:         case IMAGETYPE_TIFF_MM:
0205:             break;
0206:         default:
0207:             return (-2);
0208:     }
0209: 
0210:     //Exif情報を配列へ
0211:     if (($cls = exif_read_data($fname, 'EXIF')) == FALSE)  return (-3);
0212:     foreach ($cls as $key=>$sect) {
0213:         if (is_array($sect) == FALSE) {
0214:             $exif[$key] = $sect;
0215:         } else {
0216:             foreach($sect as $name=>$val)   $exif[$key . '.' . $name] = $val;
0217:         }
0218:     }
0219:     return 0;
0220: }

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

応用

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

参考サイト

(この項おわり)
header