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

Exiftool : まだまだこんな使い方がある!

2014年08月01日 00:00

望遠レンズ

望遠レンズ

Pentax K20D, Ricoh Rikenon XR135mmF2.8

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



Exiftooネタは前回の記事で終わる筈だっただが、ExifTool GUIの紹介に間違いがあったのと、C++を利用してのプログラムで判らなかった部分を解明し、さらにExiftoolで得られた露出補正値、これを上手くLightroomで活用する術を見つけ、同じ方法で、測光方法、フォーカスモード、さらにPentax独特の仕様情報もLightroomでフィルタリング出来たので、せっかくなのでお披露目。

少しでもExiftoolに興味がある、もしくはLightroomをもっと使いやすくしたい、そんな方は、途中、退屈話が進行するが、是非とも最後までご覧あれ!。

まずは前回の記事でExifToolGUIの記述に誤りがあった件。

1枚のファイルに対して修正が効くと書いたが、ファイルを複数選択していれば選択したファイルを一括で変更出来、コマンドラインにワイルドカードを含むファイルを入力していれば、そちらが採用されるみたいだ。

だから修正するファイルが予め判っていたら、コマンドラインからexiftoolを利用するよりも、GUI環境のこっちの方があり難い。

但し、命令そのものはexiftoolの引数をそのまま使うので、Sigma 17-70mmF2.8-4レンズがLightroomで「不明」と表示されるのを修正する場合は、ExifToolGUIで該当フォルダに移動後、中央下の「ExifTool directボタン」を押下すると、「Command」と言うテキストボックスが現れるから、そこに・・・。


-if "$LensID =~ /sigma 17-70/i" -Lens="Sigma 17-70mmF2.8-4.0 DC Macro OS HSM" -LendModel="Sigma 17-70mmF2.8-4.0 DC Macro OS HSM" *.xmp -overwrite_original


このように入力する。要するにフォルダ移動だけGUI、マウスで行って、後はコマンドラインの処理と同じ作業をする。まぁこれだけでもあり難いかもしれない。コマンドラインからの作業で一番面倒なのがフォルダの移動だから、それをマウスでやってくれちゃうのだから使わない手は無い。

※ExifToolFUIはWindowsのexiftool.exeを利用するので、スペースを含む文字列はシングルクォーテーションマークでなく、ダブルクォーテーションマークで括る必要がある

注意点はオプション引数だけで良いと勘違いしちゃ駄目。だから上を、、、


-if "$LensID =~ /sigma 17-70/i" -Lens="Sigma 17-70mmF2.8-4.0 DC Macro OS HSM" -LendModel="Sigma 17-70mmF2.8-4.0 DC Macro OS HSM"


このように「*xmp -overwrite_original」を書き忘れると、XMPファイルだけでなく、Rawファイルまで修正を加え、さらにバックアップを作っちゃうし、もしマウスでファイルを選択していたら、選択しているファイルにだけそれを採用する。

だからこういうのはその都度入力するのでなく、テストして問題なかったCommand構文はテキストファイルに保存しておく。そして使う時にテキストファイルからカットアンドペーストでテキストボックスに放り込むのが良いだろう。

次に、C++のラッパー作成にあたり、何が判らなかったか?。それは次の部分。


string opt = "-Lens\n";
if (TagInfo* info = exif->ImageInfo(argv[i], opt.c_str())) {


これはタグ情報を取ってくる部分で、ImageInfoの引数はファイル名(hoge.xmpやhoge.pef)とオプションなのだが、このオプションに「-if」が使えると仕様にか書かれているのにそれを認識してくれなかった。

そこで仕方なく、全てのファイルをチェックし、タグ情報を入手後に「もしhogehogeだったら・・・」と実に無駄な作業をしていた。これはEixfTool側のバグだと思っていたが・・・。

コマンドラインからexiffoolを利用する場合、例えば、「LensIDがSigma 17-70mmを含む文字列だったらLensにレンズ名を書き入れる」、こんな時は・・・、


exiftool -Lens='Sigma 17-70mmF2.8-4' -if '$LensID =~ /sigma 17-70/i' -overwrite_original *.xmp


となる。だから単純に、、、


if (TagInfo* info = exif->ImageInfo(argv[i], "-if '$LensID =~ /sigma 17-70/i'") {


で良い筈なのにこれだと-ifを全く認識しない。とにかくgoogleでExiftoolに書かれている文献を仰山読んだ。当然、ほとんどが海外のサイトだから英語をなんとか訳しながら・・・。それでも解が見えてこない。そもそもC++でExiftoolのラッパーを作り、それを紹介している人が、全世界でも限られ、らしいページは見つかるけど、得たい情報は一切無かった。勿論、日本のサイトも皆無。

そうなったら、考えられるありとあらゆる術を試すしかない。結果・・・。


if (TagInfo* info = exif->ImageInfo(argv[i], "-if\n$LensID =~ /sigma 17-70/i") {


上が正解。「-Lens\n-LensID\nLesnModel」、このように引数の区切りに"\n"を挿入せよと書いてあったが、-ifの次に来るのは-ifへの構文だからしてここに"\n"なんて思いもしなかったし、コマンドラインからexiffoolを利用した場合はここをシングルクォーテーションマーク(Windowsならダブルクォーテーション)で括る必要があったのにImageInfoの引数にはそれが必要ない。

製作者のサイトの仕様を見ても(私が見た限り)-ifは特殊だからこうやるべし!、なんて書かれていなかった。いやぁ、これは判らんってばさ!。

そんなこんなで前回の記事のC++のソースコードは以下のようになった。


//#define DEBUG

#define UNICODE

#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 opt = "-if\n$LensID =~ /sigma 17-70/i";
    const string lensname = "Sigma 17-70mm F2.8-4.0 DC Macro OS HSM";

    for(int i = 1; i < argc; i++) {
#ifdef DEBUG
            for (TagInfo* n = info; n; n = n->next) {
                cout << n->name << ":" << n->value << endl;
            }
#endif
        if (TagInfo* info = exif->ImageInfo(argv[i], opt.c_str())) {
            exif->SetNewValue("Lens", lensname.c_str());
            exif->SetNewValue("LensModel", lensname.c_str());
            exif->WriteInfo(argv[i], "-overwrite_original");

            cnt++;
            cout << argv[i] << " update!" << endl;
            delete info;
        }
    }
#ifdef DEBUG
    if (char* err = exif->GetError()) {
        cerr << "error = " << err << endl;
    }
#endif
    cout << "\n" << cnt << " files update!\n" << endl;
    delete exif;
    return 0;
}


デバッグ行は皆さんのヒントになるように残しているが、これを取り払えば前回の記事のソースよりも10ステップのダイエットになった。コマンドラインのexiftool、もしくはexiftool.exe、そしてこのC++のラッパープログラムも、ミソは「-if」の引数。ここで何を条件に検索してくるかだ。

では本日の目玉情報?。7月26日の記事にて、Lightroomが露出補正値でフィルタリングしてくれないから、Exiftoolでそれを行うと書いた。

でもこれはあくまでも検索した露出補正値をコンソールに標準出力するだけで、それはLightroomに反映されない。何しろLightroomには露出補正値と言うフィルター項目がないのだから・・・。

色々と思案。待てよ!、キーワードタグに露出補正値を追加すれば、キーワードのフィルタリングで任意の露出補正値の写真を検索出来るじゃないか!。

ところが色々とやってみるとどうも上手く行かない。このキーワードタグはどうやらLightroomが内部的に何かしているらしく、Exiftoolで正しい情報をxmpファイルに書き込んでもLightroom側でそれを正しい情報として処理してくれないみたい。

そこで・・・。普段は使わず(少なくとも私は使わない)、Lightroomのフィルター項目に存在しているタグを探してみた。「撮影者」、「著作権のステータス」、「ジョブID」の3つ。だったら仮に、露出補正値を「撮影者」に登録し、Lightroom上で、撮影者でフィルタリングした後、写真を全選択し、それをキーワードに書き込み(移し変えるとでも言おうか)、最後に仮に書き込んだ撮影者タグを初期化しちゃえば良い。

exiftoolが認識する撮影者タグ名は「Creator」。だから・・・。


exiftool -n -if '$ExposureCompensation == -1' -Creator=-1.00EV -overwrite_original *.xmp


こうすると*.xmpファイル全てでLightroom上の「撮影者」に「-1.00EV」が入る。キーワードで「露出補正値」を新規作成し、それを上位キーワードとし、その下位に-1.00EV(タグ名は何でも良く、単に「-1」でも「-1EV」、「-1ev」でも好き勝手に)を作り、あとはLightroomで「撮影者」にこの値が入っている写真を全選択し、実際の値部分にセット、最後に仮登録した「撮影者」の内容を削除しちゃう。

これをいちいち露出補正値毎にやるのが面倒なので(バッチファイルに全部書いちゃえば良いのだが)フォルダ内全てのファイルを一発で変更するようにPerlスクリプトを作った。


#!/usr/bin/perl

use Image::ExifTool;

my $exifTool = new Image::ExifTool;
my $i = 0;
my $ExposureCompensation = "";

foreach (@ARGV) {
	$exifTool->ImageInfo($_);
	$ExposureCompensation = eval($exifTool->GetValue("ExposureCompensation"));
	$ExposureCompensation = sprintf "%1.2fEV", $ExposureCompensation;
	if ($ExposureCompensation > 0) {
		$ExposureCompensation = "+" . $ExposureCompensation;
	}
	
	$exifTool->SetNewValue("Creator");
	$exifTool->SetNewValue("Creator", $ExposureCompensation);
	$exifTool->WriteInfo($_);

	print "$_ update!\n";
	$i++;
}

print "\n$i files update!\n\n";


これをset_exposure_compensation.plに保存したら、コマンドラインで「set_exposure_compensation.pl *.xmp」で露出補正値全てをCreatorタグ(撮影者)に書いてくれる。

二箇所でちょいと悩んでしまった。何故かPentaxカメラの露出補正値って分数記録されており、+1.5EVが「3/2」になっている。perlで分数の文字列を数字にする方法が判らなかったので、ネット検索。これは一発で出てきた。evalを使うんだって。

続いて、タグに露出補正値をセットするメソッドのSetNewValue。これがLihgtroomのキーワードタグもそうだけど、一度初期化してやらないと上書きでなく文字列をどんどんと追加していく仕様みたい。

だから初期化しないで、テストでこれを何度も走らせていると、値が「-0.5-0.5-0.5-0.5・・・」となってしまう。この方法が正しいかは何とも言えないが、SetNewValueは第二引数を与えないと内容を初期化してくれるので、とりあえずこれで今のところ問題は発見出来ない。

上述したexiftoolをコマンドラインから実行するのも、このスクリプトも、Lightroomの「撮影者」部分を上書きするので、もしここに自分の名前等を記入していたら、それが全て露出補正値に変わってしまうので、そんな方は使っていないタグを見つけて、そこに仮書き込みされたし。

本当はキーワードタグに直接書き込めれば良いのだが、うーん、1時間以上色々とやってみたが、駄目だった・・・。

まぁ運用上問題ないから、これ以上考えない事にする。とにかくこれでLightroomで露出補正値を元に写真をフィルタリングが可能となったから、まぁ作業が捗る、捗る!。

ついでに、測光モードが判ったらもっと楽しいんじゃないの?、って事でやってみた。方法は上と同じ。キーワード「測光モード(勿論名前は任意)」を新規作成し、その下に「分割測光、中央重点測光、スポット測光」と作り、「撮影者」のデータをそれに移しちゃう。

#!/usr/bin/perl

use Image::ExifTool;
use File::Basename;

my $exifTool = new Image::ExifTool;
my $exifTool2 = new Image::ExifTool;
my $i = 0;
my $MeteringMode = "";
my ($DirName, $BaseName, $ExtName) = "";
$XmpFileName = "";

foreach (@ARGV) {
    #ファイルのベースネーム、フォルダ、拡張子抽出
    ($BaseName, $DirrName, $ExtName) = fileparse($_, '\..*$');

    # 引数のファイルがPEFでなければ
    if ($ExtName ne ".PEF") {
        print "Error!!! $_, only PEF!\n";
        next;
    }

    # 測光モード名称
    $exifTool->ImageInfo($_);
    $MeteringMode = $exifTool->GetValue("MeteringMode");

    if ($MeteringMode =~ /Multi-segment/i) {
        $MeteringMode = "分割測光";
    } elsif ($MeteringMode =~ /Center/i) {
        $MeteringMode = "中央重点測光";
    } elsif ($MeteringMode =~ /Spot/i) {
        $MeteringMode = "スポット測光";
    } else {
        $MeteringMode = "不明";
    }
    
    # XMPファイルに書き込み
    $XmpFileName = $BaseName . ".xmp";
    if (-f $XmpFileName) {
        $exifTool->SetNewValue("Creator");
        $exifTool->SetNewValue("Creator", $MeteringMode);
        $exifTool->WriteInfo($XmpFileName);

        print "$XmpFileName-->$MeteringMode update!\n";
        $i++;
    } else {
        print "Error! $XmpFileName not found!!!\n";
        next;
    }
}

print "\n$i files update!\n\n";


これはPentaxの一眼レフのみに作用するのと、値はxmpファイルでなくPEFファイルに入っている。他社のカメラもそれは同じだろう。EXIF内のタグ名は「MeteringMode」なので、他社カメラならそれで実際の値をチェックされたし。

これはフォーカスモードでも利用出来る。AF-Sなのか、AF-Cなのか、はたまたマニュアルで撮ったのか。これのタグ名が「FocusMode」で、Pentaxカメラの場合、それはxmpファイルでなく、PEFファイルに記述されている。

とにかくこれと同じような作業を行えばなんでも出来ちゃう。では下は?。


#!/usr/bin/perl

use Image::ExifTool;
use File::Basename;

my $exifTool = new Image::ExifTool;
my $exifTool2 = new Image::ExifTool;
my $i = 0;
my $Sharp = "";
my ($DirName, $BaseName, $ExtName) = "";

foreach (@ARGV) {
    #ファイルのベースネーム、フォルダ、拡張子抽出
    ($BaseName, $DirrName, $ExtName) = fileparse($_, '\..*$');

    # 引数のファイルがPEFでなければ
    if ($ExtName ne ".PEF") {
        print "Error!!! $_, only PEF!\n";
        next;
    }

    # シャープネス読み込み、名称設定
    $exifTool->ImageInfo($_);
    $Sharp = $exifTool->GetValue("FineSharpness");

    if ($Sharp =~ /off/i) {
        $Sharp = "ノーマルシャープネス";
    } elsif ($Sharp =~ /on/i) {
        if ($Sharp =~ /normal/i) {
            $Sharp = "ファインシャープネス";
        } else {
            $Sharp = "エクストラシャープネス";
        }
    }
    
    # XMPファイルに書き込み
    $XmpFileName = $BaseName . ".xmp";
    if (-f $XmpFileName) {
        $exifTool2->ImageInfo($XmpFileName);
        $exifTool2->SetNewValue("Creator");
        $exifTool2->SetNewValue("Creator", $Sharp);
        $exifTool2->WriteInfo($XmpFileName);

        print "$XmpFileName, $Sharp update!\n";
        $i++;
    } else {
        print "Error! $XmpFileName not found!!!\n";
        next;
    }
}

print "\n$i files update!\n\n";


Pentaxユーザーならお判りでしょう。そう、これはシャープネスモードをLightroomの「撮影者」に書き込んでいる(これもPentax特有のものなので、xmpでなくPEF、DNGを読み込まないとならない)。

またカスタムイメージのタグは「ImageTone」なので次。面倒なのでエラーチェックなどしていないのと、これはK-5、K-5II、K-5IIs用。K-3やK-01、K-50などはカスタムイメージが増えているのでそれは各自チェックされたし。


#!/usr/bin/perl

use Image::ExifTool;
use File::Basename;

my $exifTool = new Image::ExifTool;
my $exifTool2 = new Image::ExifTool;
my $i = 0;
my $Tone = "";
my ($DirName, $BaseName, $Ext) = "";
my $XmpFileName;

foreach (@ARGV) {
    $exifTool->ImageInfo($_);
    $Tone = $exifTool->GetValue("ImageTone");

    if ($Tone =~ /bright/i) {
        $Tone = "鮮やか";
    } elsif ($Tone =~ /natural/i) {
        $Tone = "ナチュラル";
    } elsif ($Tone =~ /portrait/i) {
        $Tone = "人物";
    } elsif ($Tone =~ /landscape/i) {
        $Tone = "風景";
    } elsif ($Tone =~ /vibrant/i) {
        $Tone = "雅(MIYABI)";
    } elsif ($Tone =~ /muted/i) {
        $Tone = "ほのか";
    } elsif ($Tone =~ /bleach/i) {
        $Tone = "銀残し";
    } elsif ($Tone =~ /reversal/i) {
        $Tone = "リバーサルフィルム";
    } elsif ($Tone =~ /mono/i) {
        $Tone = "モノトーン";
    } else {
        $Tone = "不明";
    }
    
    ($BaseName, $DirrName, $ExtName) = fileparse($_, '\..*$');
    $XmpFileName = $BaseName . ".xmp";

    $exifTool2->ImageInfo($XmpFileName);
    $exifTool2->SetNewValue("Creator");
    $exifTool2->SetNewValue("Creator", $Tone);
    $exifTool2->WriteInfo($XmpFileName);

    print "$XmpFileName-->$Tone\n";
    $i++;
}

print "\n$i files update!\n\n";


こんな風に書いておけば良い。だからホワイトバランスを知りたいって時はPEFファイルに記録されている「WhiteBanance」がそれに該当するから上のスクリプトを踏まえ、、、


$WB = $exifTool->GetValue("WhiteBalance");
if ($WB =~ /auto/i) {
    $WB = "オート";
} elsif ($WB =~ /daylight/i) {
    $WB = "太陽光";
} elsif ($WB =~ /shade/i) {
    $WB = "日陰";
} elsif ($WB =~ /cloudy/i) {
    $WB = "曇天";
} elsif ($WB =~ /daylight flock/i) {
    $WB = "昼光色蛍光灯";
} elsif ($WB =~ /day white flu/i) {
    $WB = "昼白色蛍光灯";
} elsif ($WB =~ /white ful/i) {
    $WB = "白色蛍光灯";
} elsif ($WB =~ /warm.*flu/i) {
    $WB = "電球色蛍光灯";
} elsif ($WB =~ /tungsten/i) {
    $WB = "白熱灯";
} elsif ($WB =~ /flash/i) {
    $WB = "ストロボ";
} elsif ($WB =~ /color/i) {
    $WB = "CTE";
} elsif ($WB =~ /tungsten/i) {
    $WB = "白熱灯";
} else {
  $WB = "その他";
}


このようにメーカー、機種独特の仕様はLightroomでは認識してくれないから、こうやって自分で書き加えるしかない。撮影者タグからキーワードにデータを移すのは完全手作業になり、面倒には違いないけど・・・。

これで露出補正値、測光モード、フォーカスモード、シャープネス、カスタムイメージ、ホワイトバランスを使ってLightroomでフィルタリング出来るようになるんだ。exiftool万歳!。

でも問題が1つ。露出補正値、測光モード、フォーカスモード等はどれもキーワード内のタグなので、OR検索は出来てもAND検索は出来ない。露出補正値が-1で、測光モードがスポットで、フォーカスモードがマニュアルの写真を探せ!、こういう作業が不可能。

そんな時は、ライブラリフィルターは8列作れるのだから、キーワード列を複数作っちゃう。私はキーワードタグに、「撮影地(都道府県)」、「被写体」のデータもあるので、キーワードタグを5列作り、「東京都で廃墟、かつ露出補正値が-2EV以下で、分割測光、そしてマニュアルフォーカスで撮影した写真」なんてのが簡単に検索出来るようになる。

もっと複雑なフィルタリングをしたい!・・・。ライブラリフィルターは8個しか作れないのに、「Pentax K-5で、ISO6400以上、レンズが単焦点でF2.8~F4、1/15sec以下の東京で撮影した廃墟、かつ露出補正値が-2EVでカスタムイメージがナチュラル、エクストラシャープネスで連写モード・・・」。これで11個。

そんな場合は、一度、ある程度絞り込んだら、例えば「「Pentax K-5で、レンズが単焦点でF2.8~F4、1/15sec以下」、ここまでの写真をコレクション(一時的なものならクイック、今後も利用するのならスマート)に放り込んじゃえば良い。コレクションは1つのフォルダのように扱えるからそこからキーワードタグを複数列作り、フィルタリングすりゃいい。無限に検索出来ちゃう。

とにかくexiftool、そしてLightroomのキーワードタグとコレクションを上手く活用すれば、如何なる複雑な検索だって出来ちゃう。皆さんも試してみる価値はあると思う。

このネタは8月1日に掲載されるが、実際には7月27日に書いていて、すでにexiftool関連のツールを利用して、レンズ名に関してはRawファイルのデータはjpgを残して全て書き換えが終了している。今後はjpgにも設定するのと、上の露出補正値、測光モード、フォーカスモード、シャープネス、カスタムイメージをLightroomのキーワードタグに書き加えるつもりだ。

うーん、今日は調子が良いぞ~。完全ハイな状態だから言葉がサクサクと浮かんでくる!。決して危険ドラッグでぶっ飛んでいる訳じゃない。もうすぐ待望の夏季休暇!。そもそも心が浮かれているんだ。以下はexiftoolそのものの話ではなく、exiftoolの利用、PerlスクリプトやC++プログラムを作った上での四方山話を展開したい。また最後に、現在テスト中のネタも放り込んでいるので最後まで読破されたし!。

Windows用のexiftool.exeを利用するとフォルダやファイル名に日本語が入っていると特定の文字でこけるし(フォルダ名やファイル名が文字化けし、そんなファイルはないと怒られる)、EXIFデータに日本語の文字列を挿入しようと思っても文字化けする。

でもexiftool.exeと同じ動作をするPerlスクリプトのexiftoolをcygwin(Windows内にUnixの環境を構築するツール)上のシェルで動かすと全て解消される。

日本語名のフォルダだらけ、そしてEIXFデータに日本語を挿入したい意図があると、必然的にcygwinのシェルからperlスクリプトのexiftoolを使うしかなく、今後もそれは変わらないだろう。

そして、exiftool.exeの文字化けのお陰で、Perlスクリプトでラッパーを書いたり、はたまた、恐らく仕事以外では一度も使った事のないC++でexiftoolのラッパーを作ったりと、この10日くらい、結構楽しめた。

ではこれからexiftoolを利用したいと思う方は、cygwinをWindowsにインストールするべきか?・・・。

まず、本ブログで紹介した程度の、Lightroomが認識しないSigmaレンズにレンズ名を入れたり、電子接点のないレンズ情報を加えたい、その程度で、かつ、EXIFデータに加えるのが英数字ならばWindowsのcmd.exeとexiftool.exeだけで十分。

しかしどうしてもEXIF内に日本語を挿入したかったり、日本語フォルダを誤認識せずに使いたかったら、Windowsならばcygwinを導入するのが手っ取り早い。でもそれは難儀だったりもする。

そう、文字通り、難しい。cygwinは、Windowsのソフトのようにインストーラーを起動し、OKボタンを押しただけでは使える段階まで仕上げてくれない。

cygwinにもWindowsのGUI環境のインストーラーが付くが、Windowsの中にunixの環境を作るから、Unixの基礎知識を持った人でないと、インストーラーを起動した時点で何をして良いか判らなくなってしまうだろう。

「あなたは何を使うんですか?、リストの中から使いたいのを好き勝手に選んでね!」、ユーザーに丸投げタイプのインストーラーだ。私も初めてそれを見た時は「ありゃ~、こりゃ解説書でもないと無理だわさぁ~」と匙を投げた。

そんな時は問答無用のオールインストール、これで間違いなく使えるが(オールでも確か1GBくらい)、インストールしたらしたで、各種環境設定が必要なり、この段階でunixの概念やシェルの知識がなくちゃどうにもならないし、Windowsとのハイブリッドだから、cygwin独特のコマンドや使い方も覚える必要がある。

例えばWindowsしか触った事がない方、「/cygdrive/c/usr/local/bin」、これは多分フォルダを意味するのだろうまでは判るだろうが、「cygdriveってなんぞよ?」なる疑問から始まり、それをネット検索掛けるとmountなる語句が出てきて、「mountって何?」、そんな話になってしまう。

運良く、若い頃にunixを利用する機会が何年もあったから、unixの基本的な知識はあったけど、それは与えられた環境で、つまり企業の中のunixヘビーユーザーが管理者として構築したunixと言う環境の極一部の機能を一ユーザーとして使っていただけで、初めてWindowsにcygwinをインストールした時は、日本語入力すら出来なかったから、エライコッチャだった(今のバージョンは日本語にも対応しているので問題なく日本語が使える)。結局、解説書を買ったもんね。

今の時代、判らない事はネット検索で調べれば済む筈が、Ubuntu等のLinux系OSやcygwinはバージョンによって細かな変更があり、ある人の書いた「cygwinのインストールはうんたら、環境設定はかんたら・・・」なる情報も、己の環境では全く使えないものだったりする。それは市販されている書籍でも同じ。

「なんだよ!、こいつの言う通りに作業しても駄目じゃないか!」、と怒り狂ってもしょ~がない。その人が嘘を吐いているのでなく、きっとその人のパソコンの環境、cygwinのバージョンではその通りにすれば上手く行くのだろう。

試しに「cygwin インストール」、「cygwin 環境設定」、はたまた「cygwin 日本語」と言ったワードで検索されたら良いと思う。仰山ヒットし、おおよそは似通ったものだが、掲載日(今年、3年前の、5年前の記事・・・)によって細かい点で幾つか内容が違っている筈だ。どれを信用して良いか・・・(最新の情報を信じるのが良い)。

perl用のImage::Exiftoolモジュール。これをダウンロードしただけじゃ利用出来ないい。perlにそれを認識させなくちゃならないんだが、ネットで検索して、CPANからダウンロードしたExiftoolを使えとあったので、その通りにやってみたけど、何故かうちの環境では上手くない。

ふと、Exiftool作者のサイトからダウンロードしたExiftoolのREADMEに方法が書かれていたのを見つけ、その通りにやった訳。でもこける。「はぁっ?」、でしょ。でもエラーの内容を見たらmakeがねぇって怒られていただけだから、「なるほど、そう言えばうちのcygwinはmakeなんてインストールしていねぇぜ!」と、cygwinのインストーラーでmakeコマンドをインストールし、果たして上手くモジュールを認識させる事が出来た。

makeコマンドとはWindowsで言うバッチファイルみたいなもので、特定の作業を一定のルールに従って自動的に行わせる為に利用されるツール。多くはプログラミングのコンパイル、リンクに使われるが、タイムスタンプを見てのファイルバックアップをするとか活用法は多岐に渡る。だからmakeコマンドって何?、な人はPerl用のImage::Exiftoolのインストールすら出来ない。

もっと悩んだのが、前回の記事で紹介したC++でのexiftoolのラッパープログラム。あんな短いソースコードだけで構築までに何時間も掛かった。

自宅ではプログラミングなんて滅多にしないが、時折、仕事の予習、研究用とでも言おうか、そんな時の為に最低限のプログラミング環境は構築している。MicrosoftのVisual Studio expressとEclipseだ。両方ともIDE、統合環境と言い、プログラミングに特化した超高機能エディターだ。ソースコードの記述、実行ファイルの作成、デバッグ(テスト)まで行えるGUI環境。

素直にEclipce上からcygwinのg++を使えば問題が無かったのに、Eclipceから同じg++でmingwの方を使ってしまい、あっちゃこっちゃでエラーが出て、exiftool関連のクラスモジュールの中を見る気も起こらず、ならばVisuao Studioからvc++を使ったら!?、とやってみたけど同じようにエラーだらけ。

どうやらC++のExiftoolクラスはunix特有のインクルードファイルを必要とするようで、Windows用に作られたmingwのg++やVisual C++だとそれらがゴソッとないので、恐られているだけ。プログラミングがどーのではないのだ。

ふーむ、じゃぁ、cyginのg++を使ってやってみるべ!。運良くエラー無しでコンパイル、リンクが完了(それでもワーニングが幾つか出ていたけど)。これで駄目だったらもう諦めるしかなかった。ソースコードに間違いはなく、単に環境設定部分で何時間も悩むなんて馬鹿馬鹿しい。

また、将来、unixからg++を使うかも、将来役に立つかも・・・、とこのC++用のexiftoolを使ってほんのちょっと高度な(笑)、プログラミングをしようと思ったら、仕事で使っているクラス関連がg++では使えなく、新たにライブラリーをリンクさせなくちゃならなかった。

※しかも何故かそのライブラリがバグっていて、望みの結果を得られず、結局、その部分を自作・・・

こんなの一般的なWindowsプログラムならちょいちょいなのに、Eclipce、cygwin、g++環境だと、それを設定するのに四苦八苦。あーでもない、こーでもない・・・。

そこでネットで「Eclipse 設定 hogehoge」等と検索をするのだが、これまた上述と同様、サイトを開けば開くだけ異なる解が目に入ってくる。色々と覗いたけど、参考になったのは1つだけ。それ以外は嘘や間違い・・・、もとい!、嘘や間違いではなかろうが、うちの環境ではその方法では動作しない状況だった。

そもそもcygwinと言うWindowsとunixのハイブリッド仕様に無理があるのと、Eclipceも、Windows風の設定もunix風の設定も出来るから、判らない時は両方試さないとならない。上手く動作させるのに、仕事でもこんなに悩んだ事はないってくらい多くの時間を失った。

自分が作っているソースコードにミスがありそれで悩むのはしょ~がない。己の知識不足、お馬鹿さんなだけ。でも環境設定如きで、どれくらいだ?、数日全く進まなかったから、時間にしたら半日近くは悩んでいた筈だ。とっても不愉快だったりする。

環境の設定が上手く行けば、Exiftoolクラスを利用してC++でさほど悩まずにラッパープログラムを書けるのだから、無駄な労力とでも言おうか。そして・・・。

連れのMacパソコン、GUI環境にてEXIFデータを書き換えるプログラムを作る、そんな(遠い)目標があるから色々と調べているのだけど、なんだかんだとマルチプラットフォームのプログラムを作るとなれば、C++よりも、Javaかなと思い始めている。

Javaはgccやg++よりも、異なるプラットフォームへの移植が簡単で(基本的に変更なしで動く筈)、Mac用のプログラムをWindowsマシンで作るのに特別な制約はなかったと記憶する。

またJavaは、おおよそ、誰がプログラムを書いてもロジックが同一ならば似た作りになる。ソースの視認性が優れていると言い換えよう。その分、面倒臭い、そんな弊害もあるのだが、CやC++は他人のソースコードは自由度があり過ぎて読みたくないから、Javaと言う言語、結構好みだったりする。

そう言えば昨年、C言語縛りの仕事が舞い込んだ。バグ取りとちょっとした仕様変更なのと、ユーザー自身が今後もちょくちょく改良を加えるらしく、C++への変更は却下された。

エライコッチャだったなぁ。C++に慣れちゃうとCは難しい。C++ならvectorとかlistで簡単に動的配列を作れるのに今更memcpy、memsetですか!、難儀なポインタの使い方、例えば文字列の配列で一文字を抽出するのに「p[1][1]で良いのを、*(*(p + 1) + 1))」(うん?、合っているかな?、もはやそれすら判らん)、こんなのばかりが出てきたら作った奴を蹴り倒さないと気が済まない。

はたまた、昔、「char***」なんて表記を見て唖然とした事があったり、自作のリスト構造が複雑怪奇だったりすると、それを追うだけでも必死。要するにポインタを複雑にし過ぎる奴が多かった。これをお読みのCプログラミング経験者は共感してくれる方多いと思う。

ソフトウェア製作を生業としている私でも、一昔前のC言語のソースは暗号ですか?、ってのが仰山ある。一時、流行ったんだな。如何に短くコードを書くか!。己の優秀さを他人に誇示したいだけの視認性皆無なソースコード。インラインアセンブラだらけのソースコードなんて絶対触りたくない。

※今は知らないが、昔は、如何に短く、かつ難解なソースコードを書くか、そんな世界大会があった

知り合いの開発者で、数年前にN88BASICの仕事が舞い込んだそうな。勿論、今更NECのPC9801で動かすのでなく、N88BASIC互換のWindowsのBASIC言語があるんだって。MS-DOS時代の資産を活かす為、それを使わなくちゃならず、死ぬ思いをしたそうだ。

そりゃぁそうだろ。N88BASICのプログラムは、余程、きっちりとした人でないとgoto文だらけのスパゲティソースだから解析するだけでも地獄を見る(ラインデバッガとかあるのかなぁ?)。いやぁ、うちの仕事でなくて良かったと常に飲み会での笑い話になっている。そう、今、最も難しい言語、それはN88BASICだと断言出来る!。

さて、当然、このマルチプラットフォームでExiftoolのGUIアプリ製作計画は一人の人間が行うのだから、他人の書いたソースが見辛い云々は関係ない。しかもC++の方が私は慣れている。でもこの手の初めてネタってのは、ネットで似たような作業をしている方のページを見て、サンプルソースがあったら、そのまま流用するのが常。

だからそんな時の為に、誰もが同じような内容になるJavaの方が良いのかなと思うのだ。そんなこんなでJavaなんだが、Java用のExiftoolが幾つかあり、どれも実に微妙。暇がなくしっかりと解析をしていないから何とも言えないのだが、本家Eixftoolをどこかの誰かがJavaに移植したのかなぁ?、仕様が違っていて、サンプルソースを見ても「ははん?」とさっぱり判らんのだなぁ。誰もが同じ内容になっていない!(笑)。

ApacheでWEBサーバーを構築して、ブラウザ上でperlやPHP等でページを製作、それでexiftoolを動かすのが一番楽なのだろうけど、そうなると仕事と同じ作業を強いられ、趣味で作るのだからそれは絶対に嫌。WEBなんとかするのだったらやった事のないPythonを使うだろうなぁ。将来仕事で役立つかも知れず・・・。

色々と調べてみると「wxWidgets」、これはマルチプラットフォームで動作可能なGUIキットみたいで、こいつはC++やその他、Perl、Python、Ruby等のスクリプト言語にも対応しているみたいで、Javaでガリガリ書くよりも「覚えちゃえば」こっちの方が楽なのかな・・・。

頭を使う、難しい事にチャレンジする、未知の世界を覗く、これって人間の本能みたいなものだから、楽しいに決まっている。でもこういうので時間を食うと本末転倒で、やっぱり写真を撮って、それを見て、そして好みのレタッチに仕上げたりして、ニヤニヤするのが脳味噌には優しそうな気もする。

とにかくそんな本末転倒な事は馬鹿馬鹿しいから、暇を見てお勉強、作るのだから、どれを利用するにせよ、たとえJavaでも、やっぱり1年後くらいを目処にってとこだろうなぁ。とにかく上に述べた通り、プログラミングそのもので悩むのだったら時間を惜しまない。でも環境設定で悩むのは不快以外の何物でもない。

あとはねぇ、気になる情報が1つ。

Lightroomに関して調べていたらAdobeから無償で提供されているSDK(プラグインを作成する為の開発環境キット)を利用すればプラグインでライブラリフィルターそのものを再構築出来るらしい。今、Lightroomから見えていないEXIFデータ、今回述べたような露出補正値やメーカー、カメラ独特の仕様をライブラリフィルターの独立した検索項目として設定も可能だと言う。

まぁこのSDKは見た事も無いスクリプト言語を使っているし、マニュアルが日本語化されていないから、趣味の範疇を超える気がしてならない。これは誰か作ってくれないかねぇ(笑)。

一応、下に今のうちのLightroomの状態を示そう(小さい見辛かったらクリックして像を大きく!)。


2014-08-01-05

2014-08-01-03


これは今述べたLightroomのSDKを利用して、プラグインメタデータを追加したもの。値なしなるデータが入っているが、これはわざとFujifilmのカメラで撮影した写真を放り込んでいるから。

画像を見る限り、理想通りかと思われるだろうが、どうもこの情報はLightroomが内部的に持っているようで、この値をEXIFデータとして書き出す訳ではない。

だから方法は今回述べた通り、まずは仮に撮影者タグにこれらの情報を盛り込み、フィルタリング用のプラグインメタデータで移しかえる作業を強いられる。このデータがEIXF(XMPやPEFファイル)と連動して、タグ、そして内容を書き出してくれれば完璧なんだけど・・・。

でもわがままを言ってもしょ~がない。キーワードタグに全て盛り込むよりもこっちの方が遥かに見易い。当分はこのまま運用しようと思う。なんたってPentaxや他社のカメラの特別な仕様、EXIFデータをLightroomで表示出来、それで検索が可能なんだから!。

これであの糞にもならないPentax純正ソフトをEXIFデータを参照する為だけに起動する事もなくなる。これだけでも嬉しくてしょ~がない。

テスト中なので、スクリプト言語でどう作る、どこをど~いじくるとこうなる!、なる事はまだ言えないが、完成したら紹介したいと思う。とにかくLightroomのSDKは判らん!。


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



コメント

    コメントの投稿

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