[PHP]画像処理:exif_tagname関数の使い方 – EXIFタグ名の取得と活用方法

PHP

こんにちは!今回は、PHPのexif_tagname関数について、EXIFタグの名前を取得する方法と活用方法を詳しく解説します。

目次

  1. exif_tagname関数とは
  2. 基本的な使い方
  3. よく使用されるタグID
  4. 実践的な使用例
  5. エラーハンドリング
  6. 活用シーンと注意点

1. exif_tagname関数とは

exif_tagname関数は、EXIFタグIDに対応するタグ名を取得する関数です。

string|false exif_tagname ( int $tag )

2. 基本的な使い方

シンプルな例

// 基本的な使用方法
$tagName = exif_tagname(271); // "Make"が返される
echo $tagName;

// タグ名が存在しない場合
$invalidTagName = exif_tagname(99999); // false が返される

3. よく使用されるタグID

class ExifTags {
    // よく使用されるタグIDの定数
    const MAKE = 271;           // カメラメーカー
    const MODEL = 272;          // カメラモデル
    const EXPOSURE_TIME = 33434;// 露出時間
    const FNUMBER = 33437;      // F値
    const ISO = 34855;          // ISO感度
    const DATETIME = 306;       // 撮影日時

    public static function getCommonTagNames() {
        $tags = [
            self::MAKE,
            self::MODEL,
            self::EXPOSURE_TIME,
            self::FNUMBER,
            self::ISO,
            self::DATETIME
        ];

        $tagNames = [];
        foreach ($tags as $tag) {
            $tagNames[$tag] = exif_tagname($tag);
        }

        return $tagNames;
    }
}

4. 実践的な使用例

EXIFデータビューアー

class ExifViewer {
    private $knownTags = [
        271 => 'カメラメーカー',
        272 => 'カメラモデル',
        306 => '撮影日時',
        33434 => '露出時間',
        33437 => 'F値',
        34855 => 'ISO感度'
    ];

    public function displayExifData($imagePath) {
        try {
            $exif = @exif_read_data($imagePath);
            if ($exif === false) {
                throw new Exception('EXIFデータを読み取れません');
            }

            $output = [];
            foreach ($exif as $key => $value) {
                $tagId = $this->getTagIdByName($key);
                if ($tagId !== false) {
                    $japaneseLabel = $this->knownTags[$tagId] ?? exif_tagname($tagId);
                    $output[$japaneseLabel] = $this->formatValue($value);
                }
            }

            return $output;

        } catch (Exception $e) {
            error_log($e->getMessage());
            return null;
        }
    }

    private function getTagIdByName($name) {
        // タグ名からIDを逆引き
        return array_search($name, array_map('exif_tagname', array_keys($this->knownTags)));
    }

    private function formatValue($value) {
        if (is_array($value)) {
            return implode(', ', $value);
        }
        return $value;
    }
}

タグ名の変換ユーティリティ

class ExifTagConverter {
    private $cache = [];

    public function getTagName($tagId) {
        if (!isset($this->cache[$tagId])) {
            $this->cache[$tagId] = exif_tagname($tagId);
        }
        return $this->cache[$tagId];
    }

    public function getReadableTagName($tagId) {
        $tagName = $this->getTagName($tagId);
        if ($tagName === false) {
            return "Unknown Tag ({$tagId})";
        }
        return $this->makeReadable($tagName);
    }

    private function makeReadable($tagName) {
        // キャメルケースを空白区切りに変換
        return ucfirst(preg_replace('/(?<!^)[A-Z]/', ' $0', $tagName));
    }
}

5. エラーハンドリング

class SafeExifTagHandler {
    public function getTagName($tagId) {
        try {
            if (!is_int($tagId)) {
                throw new InvalidArgumentException('タグIDは整数である必要があります');
            }

            $tagName = exif_tagname($tagId);
            if ($tagName === false) {
                throw new Exception("無効なタグID: {$tagId}");
            }

            return $tagName;

        } catch (Exception $e) {
            error_log($e->getMessage());
            return null;
        }
    }

    public function validateTagId($tagId) {
        return is_int($tagId) && exif_tagname($tagId) !== false;
    }
}

6. 活用シーンと注意点

メタデータ管理システム

class MetadataManager {
    private $converter;

    public function __construct() {
        $this->converter = new ExifTagConverter();
    }

    public function analyzeImage($imagePath) {
        $exif = @exif_read_data($imagePath);
        if ($exif === false) {
            return [];
        }

        $metadata = [];
        foreach ($exif as $key => $value) {
            $tagId = $this->findTagId($key);
            if ($tagId !== false) {
                $readableName = $this->converter->getReadableTagName($tagId);
                $metadata[$readableName] = $value;
            }
        }

        return $metadata;
    }

    private function findTagId($name) {
        // 実装は省略
        return false;
    }
}

キャッシュの実装

class ExifTagCache {
    private static $cache = [];

    public static function getTagName($tagId) {
        if (!isset(self::$cache[$tagId])) {
            self::$cache[$tagId] = exif_tagname($tagId);
        }
        return self::$cache[$tagId];
    }

    public static function clearCache() {
        self::$cache = [];
    }
}

まとめ

exif_tagname関数使用のポイント:

  1. タグIDの正当性を確認する
  2. 返値のfalseチェックを忘れずに
  3. キャッシュを活用して効率化
  4. 人間が読みやすい形式への変換を考慮
  5. エラーハンドリングを適切に実装

これらの点に注意を払うことで、効率的なEXIFタグ名の処理が可能になります。

タイトルとURLをコピーしました