はじめに
画像ファイル(JPEG)にIPTCのヘッドラインやキーワードを付けて管理しているのですが(管理は主にAdobe Bridgeを使用)、画像ファイルに付けた情報をPythonで表示・編集する方法はあるのかと思い、調べてみました。
個々の画像ファイルのIPTC情報を操作するなら、Adobe Bridgeを始めとする画像管理アプリを使えば良いのですが(それでも、IPTCやExifを操作できる使い勝手の良いアプリは少ない)、複数の画像ファイルに付けたキーワードの総数や、キーワードごとの使用回数を調べる、それも再帰的に調べたいとなると、Adobe Bridgeではできそうになかったので、Pythonでやってみることにしました。
画像ファイルに付けた情報の例
参考: IPTC
使用するモジュール
本例ではpyexiv2を使います。
環境
- OS: Windows 11 Home 22H2
- Python: 64ビット版、3.11.4
インストール
pip install pyexiv2
IPTC情報を表示する
import pyexiv2
import pprint # 辞書を整形して出力するために使用
# カレントディレクトリのサンプルファイルを読み込む
img = pyexiv2.Image(r'.\sample.jpg')
# 表示 IPTC情報全部
pprint.pprint(img.read_iptc())
# 表示 一部
# IPTCのキーワードのみ
keywords = img.read_iptc()['Iptc.Application2.Keywords']
print(keywords)
# クローズ処理
img.close()
表示結果。IPTC情報全部
{'Iptc.Application2.DateCreated': '2022-02-23',
'Iptc.Application2.Headline': '冬のダム',
'Iptc.Application2.Keywords': ['2月', '冬', '雪', 'ダム', '雪景色', '青空', 'サンプル'],
'Iptc.Application2.RecordVersion': '4',
'Iptc.Application2.TimeCreated': '10:41:18+00:00',
'Iptc.Envelope.CharacterSet': '\x1b%G'}
Adobe Bridgeで画像に付けたヘッドライン、キーワードが表示されました。
表示結果。IPTC情報のキーワードのみ
['2月', '冬', '雪', 'ダム', '雪景色', '青空', 'サンプル']
型は辞書ですので、部分的に取り出すのも容易です。
複数の画像ファイルにおいて、キーワードごとの出現回数を集計する
基準となるディレクトリ配下のJPEGファイルをすべて読み込み、キーワードごとの出現回数を集計します。
import pyexiv2
import collections
from glob import glob
from tqdm import tqdm
from pprint import pprint
# 基準となるディレクトリ
base_dir = 'baseDir'
# 基準となるディレクトリ配下にあるJPEGファイルを再帰的に読み込む
glob_dir = glob('%s/**/*.jpg' % base_dir, recursive=True)
all_keywords = []
for file_name in tqdm(glob_dir):
try:
img = pyexiv2.Image(file_name)
iptc = img.read_iptc()
except Exception as err:
# IPTC情報が読めなかったファイル名とエラー内容を表示
print(f'Error file name: {file_name}')
print(f'Exception: {err}')
continue
# IPTCのキーワードを抽出して、リストに加えていく
# キーワードが登録されていないのにgetをするとエラーとなるので注意
if 'Iptc.Application2.Keywords' in iptc:
keywords = iptc.get('Iptc.Application2.Keywords')
all_keywords.extend(keywords)
# collectionsのCounterクラスを用いて、キーワードの出現回数を集計する
coll = collections.Counter(all_keywords)
# 整形して表示する
pprint(coll)
# キーワードの出現回数の結果をファイルに出力する
# キーワード数が多いと画面では見切れてしまうので、必要に応じて
with open('aggregate_keywords.txt', 'w', encoding='UTF-8') as f:
pprint(coll, stream=f)
# クローズ処理
img.close()
集計結果
Counter({'風景': 1273,
'人物なし': 1232,
'無人': 1231,
'屋外': 1217,
'日本': 1175,
'青空': 1131,
'背景': 1131,
'空': 1097,
'背景素材': 996,
'素材': 992,
(中略)
'ハロ': 1,
'日暈': 1,
'気象現象': 1,
'日': 1,
'輪': 1,
'洪水吐': 1,
'水たまり': 1})
キーワードごとの出現回数を求めることができました。