にほんブログ村 写真ブログ デジタル写真へ
にほんブログ村のランキングに参加中です

Exiftool : まとめ

2014年07月30日 00:00



蝶

Pentax K20D, Tokina RMC 70-210mmF3.5

※ブログに視覚要素を加えるlightboxを導入しています。上記画像をクリックすると少し大きな画像をポップアップして見る事が出来、暗くなった部分をクリックするか、画像下部のCloseをクリックすると元に戻ります。



いやぁ、Exiftoolだけで5回を迎えた。これを書いている今、7月22日であり、ようやくEixftoolネタの第1回が掲載されている訳で、これから5回に渡り、どれだけ本ブログをお読みの方が食いついてくれるか不安でしょ~がない。

と言うのも・・・。

Exiftoolを利用している、利用したいなんて方は・・・。

  1. Lighroom使用者、かつSigmaレンズの愛用者
  2. 電子接点のないレンズ(もしくはマウントアダプターを介して他社のレンズ)、またはフィルムカメラ愛好家
  3. 写真をネット掲載するに当たり、GPSデータを含め、一括でEIXF内容を削除したい方
  4. GPSデータを抽出し、地図アプリなどとリンクさせようと考えている方
  5. キャラクターユーザーインターフェースを苦にしない方


要するにマニアックな人間がこれを利用しているんだと思う。世界的に画像、写真関連ではメジャーなツールではあるようだが、ではこれに関して詳細を書いている日本のサイトが仰山あるのか?、答えはノー。少なくとも私自身は日本のサイトでExiftoolに関して参考になったページは無かったように感じる。

Windowsユーザーなら、exiftool.exeだけでも(日本語を含むパス名、ファイル名を使わなければ)おおよその作業は出来ちゃう。でも問題は5番。cmd.exeを起動した事も無い、バッチファイルって何?、そんな人だって多いと思うし、そうならexiftool.exeだけでも結構敷居が高い。

増してやWindows上でUnixの環境を作り、Unixのシェルからperlで書かれたスクリプトを動かすなんて・・・。

連れはかつて、googleやyahooの検索エンジンと同等の動作をする全文検索が可能なNamazuをMacで動かしていたような人だが、仕事で必要に駆られ使い方を無理に学んだだけで(分厚い本を買っていたなぁ)、「趣味で同じような作業をするのはご免こうむる、あんたが出来るんだからあたしの分までやっといて~!」。まぁ普通の人はそうだろうな(笑)。

私だってLOVE PENTAX?さんのLightroomでレンズ名を任意に編集する方法を読んでいなければ、Ligthroomで「不明」と表示されたレンズデータを修正するなんて考えもしなかった。

だから冒頭に書いたように、今日でExiftoolネタは5回目。果たして皆さんが付いて来て下さっているか・・・。まぁ一連の記事は備忘録のようなものだから自分にとって意義があれば良いのかな。と言う事で今日は正にその備忘録を。



ExifTool by Phil Harvey

Exiftoolを提供しているサイトのトップページ。ここからオプション解説やら、スクリプトの作り方、Exiftoolを利用したアプリケーション紹介など、多くリンクされているので、とにかくここから始める事。時間がある方は一通りのリンクを辿ってみると良いだろう。

時間の無い方はまずは下方にスクロールし「Additional Documentation and Resources」と書かれた部分を参照し、ここのリンクは(斜め読みでも良いので)全て辿るべし。

※Perlで作られたExiftool本体はtarで圧縮されたファイルをダウンロードするので、別途tarが解凍出来る解凍ツールが必要だ(vectorなどで仰山見つかる)



その「Additional Documentation and Resources」で最も重要かつ基本部分。exiftool.exe、もしくはperlで作られたexiftoolをコマンドライン上から使うのならその引数(オプション)やタグを理解しないとならない。

exiftool Application Documentation

ExifTool Tag Names



EXIFの中身を参照したい。またタグの名前の一覧が欲しい。また修正する箇所も、枚数も少ない。そんな場合は、コマンドラインからexiftoolを使うよりもGUI環境で閲覧、変更出来るソフトを使った方が手っ取り早い。

ExifToolGUI for Windows

これはExiftoolのラッパーなので別途、Exiftool本体(Exiftool.exe)が必要になる。このGUIツールで残念なのが、データの修正がちょっと面倒な点。グリッド部分で修正が可能なら非常に優れているツールなんだけど、修正には、exiftool directボタンを押して、そこにコマンドラインでexiftoolを使うように引数を与えなくちゃならない。

まぁexiftoolをコマンドラインからパチパチするのに慣れちゃえば、なんて事はないから、1枚のファイルに対して幾つかの値をを変更するには使えるツールだ。

でも大量のファイルを一気に修正したり、1枚のファイルだけど、変更箇所が仰山ある、そんな場合は、コマンドラインからパチパチするか、perlスクリプトを自分で書くか、はたまた下で紹介している引数「-@」を使うのがベスト!(個人的には-@を使うのが一番簡単だと思う)。

※8月1日追記・・・ExiftoolGUI、複数のファイルでもEXIF内容を一括変更出来るのが判った。詳しくは8月1日の記事をどうぞ!



Exiftool.exe(もしくはPerlで書かれたexiftool)の基本的な使い方

exiftool ファイル名
   ex) exiftool hogehoge.xmp

これはEXIFの中身全てをただ標準出力に垂れ流すだけなので、テキストファイルにリダイレクトしてエディターで詳細をチェックするのに使っている。「exiftool hogehoge.xmp > hoge.txt」、こうすればhoge.txtで全て参照出来る。

windows版のexiftool.exeはファイル名にワイルドカード(「*」と「?」)が使え、unxi版のperlで書かれたexiftoolは正規表現が使える。

1枚の写真を参照するだけなら上述したExifToolGUIを使った方が楽な気もする。


exiftool -タグ名
   ex) exiftool -FileName -Lens -FocalLength hoge.xmp

見たいタグ内容だけを見る時。この時にアルファベットの大文字、小文字は関係ない。-Lensと-lens、-LeNsは同じ作用をする。

またタグ名には正規表現が使える。「-Lens.*」とやれば「-Lens、-LensID、-LensModel」などを表示してくれる。FocalLengthとFocalLengthIn35mmFormatの2つを表示したければ、面倒なので「-FocalLen.*」とすれば良いし、露出補正値なんて「ExposureCompensation」だからして「ExposureC.*」で良い。
但し、cygwinのシェルからexiftoolを起動する場合、正規表現を使うタグ名はシングルクォーテーションで括る必要がある。「exiftool -FileName '-FocalLen.*' hoge.xmp」

exiftool -s or -s1 or -s2 or -s3 or -S

※タグ名以外のオプションは大文字、小文字が区別される

通常、タグ名は見やすいように例えば「Raw File Name」、「Focal Length」と表示されるが、-s、-s1、-s2を付けると正式タグ名と内容が表示され(RawFileName、FocalLengthなど)、-s3にするとタグ名は表示されず、内容だけが表示される。そして-s2と-S(大文字)は同じ作用をするみたいだ。

exiftool -t or -T

-tはタブ区切り、-Tは表形式で標準出力される。言い換えると-tは縦に複数行に渡って表示され、-Tは横1行に表示される。大きく変化するのはワイルドカードや正規表現で複数のファイルを与えた場合。

exiftool -if
   ex)exiftool -if '$LensID =~ /Sigma/' -RawFile.* -FocalLength *.xmp

※Windowsのexiftool.exeだとシングルクォーテーションはダブルクォーテーション

これには論理演算子、つまりand、orも利用出来る。例えばSigmaの17-70mmかPentaxの17-70mmのいずれかで撮影されたものを抽出したい時は、、、

exiftool -if '$LendID =~ /Sigma 17-70/ or $LenID =~ /DA 17-70/' *.xmp

そして論理演算時のandは、-ifオプションを2つ設ける事でも実現する。次の2つは同じ作用をする(正規表現のパターンマッチングで「/パターン/i」とした場合は大文字小文字を区別しない)。

exiftool -if '$LendID =~ /Sigma 17-70/ and $Model =~ /K-5/' *.xmp
exiftool -if '$LendID =~ /Sigma 17-70/' -if '$Model =~ /k-5/i' *.xmp

またこの-ifはどんなタグにも利用出来るので、例えば・・・。

上述の通り、Windowsのexiftool.exeはファイル名に正規表現を使えない。hoge01~hoge09までのファイルがあったとし、対象としたいファイルがhoge01、03、05、07だったとする。でもexiftool.exeだと出来ない。だから、、、

exiftool -LensID -FocalLenth -if "$RawFileName =~ /hoge0[1357]/" hoge0*.xmp

これで対象ファイルがhoge01、03、05、07になってくれる。


exiftool -n

これはifと同時に活用すると威力を発揮するもので、タグの要素を数値として扱ってくれる。良く使うのは焦点距離と露出補正値だろう。焦点距離が24mmだったとする。でもメーカーによってそれが"24"として保存されていたり、"24"だったり、"24.0"だったりする。だから、、、

exiftool -n -if '$FocalLength == 24' -RawFileName -FocalLength *.xmp

とすると良いだろう。また露出補正値も+0.5が実際には"1/2"と分数で保存されていたりするから、、、

exiftool -n -if '$ExposureCompensation == 0.5'
exiftool -n if '$ExposureCompensation <= 0

なんて使い方になる。しかしこれまた困った事に文字列として扱う必要があるものまで数値にしちゃうみたいで・・・。

exiftool -n if '$ExposureCompensation <= 0 and $LensID =~ /Sigma/' *.xmp

これは駄目。そこで・・・。

exiftool -n if '$ExposureCompensation <= 0 and "$LensID =~ /Sigma/"' *.xmp

上のように文字列として扱いたいタグをダブルクォーテーションマークで括ってみたところしっかりと動作してくれた。これがWidnwosのexiftool.exeだと、、、

exiftool -n if "$ExposureCompensation <= 0 and "$LensID =~ /Sigma/"" *.xmp

とシングルクォーテーション部分をダブルクォーテーションマークに変える必要がある。


exiftool -exec

これは-execより前に記述した引数をとりあえず実行してくれる。例えば上の-nオプションを付けて文字を数字として扱う場合、文字として扱いたい時に面倒な事になるので、、、

exiftool -n if '$ExposureCompensation <= 0' -exec -if '$Lens =~ /sigma/i'

こうすると、-execまでを先ず実行するから、露出補正値は数字として扱い、-exec以降には-nオプションがないので、文字列として扱う。記述量が多くなるが、こっちの方が判り易いでしょう?。

この-nと-execを覚えておけばかなり複雑なフィルタリングが出来るだろう。


exiftool -overwrite_original
exiftool -overwrite_original_in_place

この2つは書き込み命令。前者がファイルの上書きし、後者は上書きして元ファイルのバックアップを作ってくれる。

ただ、元ファイルのバックアップって必要か?。特にサイドカーのxmpでなくRawfileそのものを修正していたら、Rawfileそのままがバックされるから、ハードディスクの残り容量がどんどんと減っていく。

それとデフォルトでは後者が採用されるようなので、バックアップの必要がなく、上書きするだけだったら必ず-overwrite_originalオプションが必要なる。

exiftool -タグ名=文字列
  ex)exiftool -FocalLength='500' -FocalLengthIn35mmFormat='750' -overwrite_original hogehoge.PEF

これを行うとタグの要素をその文字列にし、ファイルに書き込んでくれる。



とりあえずこれだけ覚えていればおおよそ扱えると思う。私もシェル上からexiftoolを使う時はここで書いた事、オプションしか使っていない。

しかし・・・。

変更箇所が仰山あった場合、コマンドラインから一字一句ミスなく入力するのか?。フィルムをデジタル化したら、少なくともカメラ名、レンズ名、絞り、シャッター速度、露出補正値、日付、時間は入力したい。人によってはさらに複数の要素を加えたい筈だ。

そんな時に使えるのが「-@」オプション。これはテキストファイルに書かれたタグとその内容に変更してくれる。

exiftool -@ テキストファイル名

まず下を実行する。引数の意味が判らなくてもおまじないと思って!。

exiftool -args -G1 --filename --directory hoge.xmp > hoge.txt

するとhoge.xmpの全ての省略なしの正規のタグ名と要素の書かれたhoge.txtを出力してくれる。それをエディターで開いて、必要な部分だけ残してあとは削除し、上書きするか、必要な部分だけを取り出して新たなファイルに書き出す。勿論、cygwinなら文字コードはUTF-8(Windowsでも日本語を書き出したい時はUTF-8で保存するのかな?)。

例として以下を取り出してみた。

-XMP-tiff:Model=PENTAX K-5
-XMP-microsoft:LensModel=Sigma 17-70mm F2.8-4.0 DC Macro OS HSM
-XMP-aux:Lens=Sigma 17-70mm F2.8-4.0 DC Macro OS HSM
-Composite:LensID=Sigma 17-70mm F2.8-4.0 DC Macro OS HSM
-XMP-exif:ShutterSpeedValue=1/90
-XMP-exif:FocalLength=200.0 mm
-XMP-exif:FNumber=8.0


カメラ名、レンズ名、シャッタースピード、絞り、焦点距離だ。これを任意の値に書き直し、foo.txtに保存。あとは、、、

exiftool -@ foo.txt bar.xmp

とすれば良い。foo.txtの中身をbar.xmpにセットしてくれるのだ。これなら変更したい内容が仰山あっても簡単に変更出来ちゃうでしょ?。勿論、-ifの併用も出来る。

exiftool -if '$XMP:DateTimeOriginal =~ /2014/' -@ foo.txt -overwrite_original *.xmp

これは2014年に撮影された写真だけをfoo.txtの内容をxmpに上書きする。

EIXFデータって規格だから、フィルムカメラで撮影し、デジタル化したjpgやtiffファイルでも手持ちのデジタルカメラのEXIFデータがそのまま使えると思う。

-XMP-tiff:Model=Pentax LX
-XMP-microsoft:LensModel=SMC A50mmF1.4
-XMP-aux:Lens=SMC M50mmF1.4
-Composite:LensID=SMC M50mmF1.4
-XMP-exif:ShutterSpeedValue=1/125
-XMP-exif:FocalLength=50.0 mm
-XMP-exif:FNumber=F2.8


上のように書き換えればLightroomでもカメラ、レンズ名などでフィルタリング出来る筈。

これは変更箇所が多い場合に有効であるが、キー入力が苦手な方は1つ2つの変更でもファイルから読み込むような手法を取った方が楽だろう。



exiftoolを紹介している日本のサイト、ブログを見ていると他にも-P、-m、-vなどを付けている人が多いが、この辺は普通に使う分には必要がない筈。不安なら exiftool Application Documentationでそれぞれの意味を確認されたし。

-Pはタイムスタンプ(撮影日時でなくxmpやPEFファイルの更新日時)を変更しないような指示みたいだから、これを付けた方が良いのかもしれないが、更新してくれた方がファイルをバックアップする際、バックアップツールは更新日時で見ている事が多いから、あえて-Pは付けていない。



私の場合、xmpファイルのlightroomで記入したキーワードの内容を参照し、同名のpefファイルの焦点距離を書き換えると言う特殊な作業を必要としたので、Perlのモジュール、Image::Exiftoolを利用してスクリプトを書く羽目になったが、通常はコマンドラインからexiftoolを使うだけでほとんどの作業は可能だろう。

注意点として・・。

「ネットの情報は鵜呑みにするな!」

これは皆さん、徹底して頂きたい。こうやって5回もネタを書き、すでにexiftoolやPerlスクリプトで運用して、今のところも問題は発見出来ないが、exiftoolの全てを理解したわけも無く、パソコンの環境が異なれば違った結果になるかも知れず、また勘違いもあるかもしれず。実際に試される際は、必ずテストフォルダを作って、その中で色々と調査して欲しい。



最後に、7月26日の記事で紹介したSigma 17-70mmのレンズ名をLightroomで認識させるperlスクリプト、これをC++で書くとこんな感じになる。


#define UNIDOCE

#include <iostream>
#include <stdbool.h>
#include "../inc/ExifTool.h"
using namespace std;

int main(int argc, char** argv) {
    if (argc < 2) {
        cout << "Usage : cp_set_s1770 [filename]" << endl;
        cout << "    ex) cp_set_s1770 *.xmp" << endl;
        return true;
    }

    ExifTool* exif = new ExifTool();
    int cnt = 0;
    const string LensName =  "Sigma 17-70mmF2.8-40.0 DC Macro OS HSM";
    const string Pattern =  "Sigma 17-70";
    const string ExifOption = "-LensID\n";

    for (int i = 1; i < argc; i++) {
        if (TagInfo* info = exif->ImageInfo(argv[i], ExifOption.c_str())) {

            for (TagInfo* n = info; n; n = n->next) {
                string value = n->value;

                if (value.find(Pattern, 0) == string::npos) {
                    continue;
                }

                exif->SetNewValue("Lens", LensName.c_str());
                exif->SetNewValue("LensModel", LensName.c_str());
                exif->WriteInfo(argv[i], "-overwrite_original");

                cout << argv[i] << " update!" << endl;
                cnt++;

                delete info;
            }
        }

    }

    cout << "\n" << cnt << " files update!\n" << endl;
    delete exif;
    return 0;
}


C++ Interface for ExifTool (by Phil Harvey)から、Exiftool本体をダウンロードし、解凍して上のコードと一緒にビルドしてやれば使える。

このC++用のExiftoolクラスモジュールは本体ではない。あくまでもPerlで書かれたExiftool、もしくはexiftool.exeを呼び出す為のクラスに過ぎず、どちらかがないと動作しない。今回はExifToolのコントラスタを引数無しで呼び出しているのでデフォルトでperlで書かれたexiftoolが本体となる。new ExifTool("exitftool.exe")とするとpathの通った場所にあるexiftool.exeが利用される。

つまり、Perlを使える環境にあり、スクリプトも自作出来る、もしくはexiftool.exeで十分、そんな方はわざわざこんなラッパープログラムをC++で作る必要はない。この程度なら処理スピードも無視して良いだろう。

PerlとC++をご存知の方は、先日作った上と同じ結果を得るPerlスクリプトとの違いがお判りになるだろう。EXIFデータを得る部分、C++ではTagInfoと言う構造体を一方向のリストにしているから、1つ1つのタグと値を見るにはfor文で回すしかない。ここがもっと良い方法があったろうにと思う。

TagInfoの中には色々な情報が入っているようだが、ユーザーが必要なのはタグ名とその値だけだから、少なくともタグ名と値の参照に関してはハッシュ(Map)にしちゃえば、配列の添え字にタグ名を利用出来、Perlとほぼ同じ作りに出来る筈。

それとこのクラスモジュールはunix系、もしくはcygwinを想定して作られているようで、MicrosoftのVC++、はたまたg++でもWindows専用のmingwバージョンではコンパイルすら出来ない。unix特有のインクルードファイルを必要とするからだ。WEBをウロチョロしているとVC++でも作っている人がいるみたいなので、こけないような、なんらかの方法はあるんだろう。

だからWindowsユーザーで、Exiftoolクラスモジュールを用いたプログラムをC++で書きたい、そんな方はcygwinを入れるか、VM ware等を導入して、仮想パソコンから今ならUbuntuをインストールするしかない。そんな面倒な作業はご免だろうから、素直にPerlスクリプトを使うのが最良の策と結論付けた(Perl本体とExiftoolモジュールのインストールが必要だが)。

これを作るに当たり、一箇所、物凄く悩んだ。ImageInfoメソッドがPerlのそれと仕様が異なり、ここにexiftoolのコマンドラインのオプションを引数に与えられる。だから「-if」で該当するデータだけ取ってこれる筈で(仕様にも-ifが使えるなる事が書かれている)、それが可能なら、perlとほとんど同じコード量になるのだが・・・。

色々とやったけど駄目だった。上述した通り、最終的にはexiftoolが実行されるのだから、「-if」は使える筈なんだ。exiftool側のバグでなかったら、何かがおかしい(exiftool側のバグっぽいとは思うんだけど)。今後も暇を見て研究したいと思っている。またC++だからと、exiftoolのメソッドの引数用の文字列をstirngで宣言しちゃうと、呼び出すところでこける。仕様を見るとchar*になっていた。

※先日、cygwinはワイルドカード展開をシェルが行うと書いたが、MicrosoftのVC++だと専用のオブジェクトファイルをリンクしないと展開されない筈だから、g++が勝手に展開してくれているみたい(しかも正規表現までもが使える)。この手の小ネタツールはワイルドカード、正規表現展開をやってくれた方が良いから、こういうプログラムはVC++で作るよりもg++の方が楽なのかも・・・



本日の写真、40年以上前のTokinaのKマウント用、70-210mmF3.5を使っている。前回の記事の写真もそうだが、Pentax K10D、K20Dを使っていた頃までは結構、この手の電子接点のないレンズを多用していた。

ところがK-7、K-5からはほとんど使っていない。単焦点レンズを使う時もFA28mm、FA50mmの使用率の方が高い。まっ、それだけMFでピントを合わせるのがかったるくなったって事だなぁ~。


にほんブログ村 写真ブログ デジタル写真へ
にほんブログ村のランキングに参加中です



コメント

    コメントの投稿

    (コメント編集・削除に必要)
    (管理者にだけ表示を許可する)