はじめに
写真のJPGファイルに、撮影日時や場所などを記録することができます。ドローン等で撮影された写真にタグ情報が書かれていることがあります。それらは一般的なフォーマットに従って記録されているようです。それらを読み書きしたいのが目的です。
GPS Exif については多くの記述があります。なので、ここでは情報が少ないと思われる xmp についてメモしておきます。なお、読むことはできるのですが、書くところはうまくできていません。(涙)
準備: xmp-toolkit のインストール
XMPとは
どうやら、Adobe が定義し、各ファイルにXML形式のテキストで情報をファイルのヘッダに加えるために用いていたようです。詳しくは分かりません。^^;)
なので、例えば、less コマンドで見ると、テキストのXMLの部分はそのまま読めます。
おじさんはLinux環境(WSL)ですが、
- less でファイルを開き
- 「binaryだけど開くか」と聞かれるのでYes とし
- xml という文字列を検索する(スラッシュ xml リターン)と、
<x:xmpmeta xmlns:x="adobe:ns:meta/">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="DJI Meta Data"
xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
xmlns:exif="http://ns.adobe.com/exif/1.0/"
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/"
xmlns:drone-dji="http://www.dji.com/drone-dji/1.0/"
xmp:ModifyDate="2018-12-14"
xmp:CreateDate="2018-12-14"
tiff:Make="DJI"
tiff:Model="FC6310R"
dc:format="image/jpg"
drone-dji:AbsoluteAltitude="+255.92"
...
のように見えます。これらの情報を読み書きしたい、というのが目的です。
python では
便利なツールはもちろん存在します。
python3 -m pip install python-xmp-toolkit
Adobe からXMP-Toolkit-SDKがソースごと公開もされています。組み込みやスマホアプリで利用できるのかな。
https://github.com/adobe/XMP-Toolkit-SDK
xmp のタグの値を読む
使い方はpython-xmp-toolkit のDocに書かれていて、それをフォローするだけで問題なかったです。メモしておきます。
ファイルを読む
from libxmp import XMPFiles
xmpfile = XMPFiles( file_path="./100_0020_0001.JPG", open_forupdate=True )
xmp = xmpfile.get_xmp()
エラーが出なければ読めています。^^;) いろいろxmp の中身を調べることができます。
値の取得
先のサンプルでは
tiff:Make="DJI"
という行がありました。これを "tiff:Make" というkey に対して value である "DJI"を直接取得したい。そのためには、2ステップ必要です。
namespace の取得
まず、tiff のnamespace (URI)を取得します。
In[]: xmp.get_namespace_for_prefix("tiff")
Out[]: 'http://ns.adobe.com/tiff/1.0/'
あらかじめadobe が定義されているnamespace もありこれはライブラリからも参照できます。
In []: libxmp.consts.XMP_NS_EXIF
Out[]: 'http://ns.adobe.com/exif/1.0/'
変数名は直接ソースの "Common Namespaces" をみて知ることもできます。
property を取得する
tiff:Make というタグの値を読むには、さきほどのtiffに対応するnamespace を指定してあげます。
In []: xmp.get_property(xmp.get_namespace_for_prefix('tiff'),'Make')
Out[]: 'DJI'
namespace内にそのキーワードがあるかを事前に確認することで、エラーを未然に防げます。
In []: xmp.does_property_exist(xmp.get_namespace_for_prefix('tiff'),'TEST')
Out[]: False
書く
正確には「書き換える」ができる「はず」なのですが、実は。。。
まず、xmp の値をsetします。
In []: xmp.set_property(xmp.get_namespace_for_prefix('tiff'),'Make', 'some/makers')
In []: xmp.get_property(xmp.get_namespace_for_prefix('tiff'),'Make')
Out[]: 'some/makers'
ファイルに書くには、xmpfileにput して file を close する必要があるようです。
In []: if xmpfile.can_put_xmp(xmp):
...: xmpfile.put_xmp(xmp)
...: xmpfile.close_file()
で良いはずなのですが。。。結果は正しく書き換えられていませんでした。手順が違うのかバグなのか分かりませんが、とりあえずここまでメモしておきます。実行時にエラーは発生しません。
メモ
とりあえず読むことだけできる、という状態でした。以下自分の課題:
- 各 namespace にあるタグを事前にすべて取得できるか?
- 書き込みの動作確認
以上。(2020/08/08)