2024-10-19

EmacsからファイルのXMPメタデータを取得・設定する

XMP(Extensible Metadata Platform)というメタデータを記述するための仕様があります。

https://developer.adobe.com/xmp/docs/

https://developer.adobe.com/xmp/docs/XMPSpecifications/

メタデータというと例えばタイトル、作成者、作成日、内容説明、ラベルといったものが代表的ですが、それに限らずあらゆる関連情報を表現することが出来る拡張可能な枠組みがXMPです。

例えば XMPSpecificationPart1.pdf というPDFファイル(バイナリ)の最後の方には次のようなXMLテキストが含まれています。

...バイナリ略...
<?xpacket begin="(略)" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.0-c316 44.253921, Sun Oct 01 2006 17:14:39">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:dc="http://purl.org/dc/elements/1.1/">
         <dc:format>application/pdf</dc:format>
         <dc:title>
            <rdf:Alt>
               <rdf:li xml:lang="x-default">XMP Specification Part 1: Data Model, Serialization, and Core Properties</rdf:li>
            </rdf:Alt>
         </dc:title>
         <dc:creator>
            <rdf:Seq>
               <rdf:li>Adobe Systems Incorporated</rdf:li>
            </rdf:Seq>
         </dc:creator>
      </rdf:Description>
      <rdf:Description rdf:about=""
            xmlns:xap="http://ns.adobe.com/xap/1.0/">
         <xap:CreateDate>2012-03-21T08:55:04Z</xap:CreateDate>
         <xap:CreatorTool>FrameMaker 8.0</xap:CreatorTool>
         <xap:ModifyDate>2012-03-21T08:57:17-07:00</xap:ModifyDate>
         <xap:MetadataDate>2012-03-21T08:57:17-07:00</xap:MetadataDate>
      </rdf:Description>
      <rdf:Description rdf:about=""
            xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
         <pdf:Producer>Acrobat Distiller 8.1.0 (Windows)</pdf:Producer>
         <pdf:Copyright>Copyright 2012, Adobe Systems Incorporated. All rights reserved.</pdf:Copyright>
      </rdf:Description>
      <rdf:Description rdf:about=""
            xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/">
         <pdfx:Copyright>Copyright 2012, Adobe Systems Incorporated. All rights reserved.</pdfx:Copyright>
      </rdf:Description>
      <rdf:Description rdf:about=""
            xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/">
         <xapMM:DocumentID>uuid:3806c052-1c0d-4599-b3ff-38c0441bbb3a</xapMM:DocumentID>
         <xapMM:InstanceID>uuid:abc82103-c360-4b74-8812-ff4c81eceaea</xapMM:InstanceID>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
...空白文字略...
<?xpacket end="w"?>
...バイナリ略...

これによって、このPDFのタイトルが「XMP Specification Part 1: Data Model, Serialization, and Core Properties」、作成者が「Adobe Systems Incorporated」、作成日時が「2012-03-21T08:55:04Z」であることを示しているわけです。

XMPはJPEGファイルの中にも埋め込まれていることがあり、様々な撮影情報が記録されていることがあります。

写真のメタデータと言えばExifが代表的ですが、私の使っているカメラではカメラ内で設定したレーティング(写真の評価)だけがXMPとして記録されるようになっていました(それ以外の撮影情報は全てExifで記録されていました)。

また、写真編集ソフトや各種ビューアもこのXMPを利用するものが多いです。沢山ある写真を評価したり分類したりしたときに、その情報をサイドカーファイルと呼ばれるXMLファイル(IMG0001.JPG.xmpのようなファイル名)に保存するようになっているソフトが多くあります。darktableにいたっては現像のための全てのパラメータをサイドカーファイルに保存します。サイドカーファイルは少々煩わしい存在ですが、メタデータをネットワークストレージを介して共有したり他のソフトと交換したりするのには最適でしょう。

というわけで、EmacsからもこのXMPで書かれたメタデータを読み書きするためのライブラリを作成しました。

misohena/el-xmp: Emacs XMP (Extensible Metadata Platform) Library

今のところ基本的な情報を読み書きするためのコマンドやDired上でメタデータを元にマークするコマンドくらいしかありません。

サイドカーファイル(拡張子が.xmpのXMLテキスト)からの読み取りはもちろん、JPEG内のAPP1セグメント内にあるXMPパケットも読み取れるようになっています。その他の場合は汎用的なパケットスキャン(<?xpacket を探す)が使われますが、確実に読み取れるとは限りません。

保存は全てサイドカーファイルに対して行われます。一応パケット内に書き戻すことも可能なのですが、危ないのでデフォルトでは無効になっています。

Diredでマークするときなど、数千ファイルくらいあると読み取りにかなりの時間がかかります。一応Emacsのセッション中だけ有効なキャッシュ機構があるので、二回目以降は速くなるはずです。

永続的なファイルメタデータキャッシュ機構もそのうち作りたいと考えています。

Diredでレーティングを元にjpgファイルをマークしてimage-diredで表示させた例
図1: Diredでレーティングを元にjpgファイルをマークしてimage-diredで表示させた例