Lightroom SDK 6.0を使う
今更ながら、一昨年(2015年)8月頃にリリースされたLightroom SDK 6.0(以下、LRSDK6と記載)を使ってみました。というか、私の用途に使えそうなことに今になって気付いたため、このタイミングで試してみたという表現の方が適切かもしれません。
はじめに
Lightroom管理下の画像の現像設定を外部から操作したいと常々思っていました。コマンドラインオプションが無いものかとか、APIが無いかとか過去にいろいろと調べたのですが、当時はありませんでした。正確には当時からSDK自体は存在したものの、現像パラメータを触れないもので、私のやりたいことは実現できないものでした。このため、LightroomのGUIからポチポチと調整する以外に現像設定を変更する手段はありませんでした。
もちろん、1枚1枚個別に現像設定を調整したい普通の写真は、GUIで調整できればそれで何も困りません。パラメータ変更とそれに応じた画像の変化を目視確認しながら調整するのが普通なので。ですが、インターバル撮影した一連の大量の画像ファイル群に対してそれは無理難題です。数百枚から数千枚の画像群の現像設定を個別に調整することなど、人間のやるべき作業ではありません。もちろん、現像設定を他の画像にコピーすることはLightroomの標準機能で可能なので、ホワイトバランスや露出が変化しないシーンでインターバル撮影した画像群の現像にはそれほど困りません。ですが、夕暮れや夜明けなど、ホワイトバランスも露出も激しく変化するシーンでは困ったことになります。カメラのオートホワイトバランスや、露出制御が相当に賢ければ撮影時の設定のまま現像すれば良いですが、現実には機材によっては1枚撮影する都度色温度が上下にぶれたり、露出プログラムの閾値付近の光量で露出ステップが変わったりします。特にホワイトバランスに関してはふらつきが目立つ事が多く、これらは映像化した際に不自然なちらつきの原因となります。ので、どうにかしたかったのです。
で、LRSDK6になってLrDevelopControllerとLrSelectionが追加されていました。前者を使うことで現像設定を調整可能となり、後者を利用することで処理対象とする画像の選定が可能になります。この2つが無かった頃のSDKは何の役に立つのか個人的には想像つきませんが、ともかくLRSDK6では私のやりたいことができそうです。
導入
以下のURLの末尾にLRSDK6のダウンロード用リンクがあります。
Adobe Photoshop Lightroom CC 2015/Lightroom 6 SDK License Agreement | Adobe Developer Connection
(ちなみに係争時は"Tokyo District Court in Japan, when Japanese law applies"とあるので、外資にしては珍しく東京地方裁判所で日本の国内法準拠で裁判に応じてくれるようです。もちろん、そんな予定はありませんが。)
インストール
インストールとか書きつつも、いわゆるインストール的な作業はありません。このSDKは実行体やDLLやJARといった類ではありません。
ダウンロードしたZIPを適当に展開するだけです。すると以下のディレクトリ群が生成されます。
+---API Reference | \---modules +---Manual \---Sample Plugins +---creatorfilter.lrdevplugin | +---mac | \---win +---custommetadatasample.lrdevplugin | \---strings | \---en +---flickr.lrdevplugin +---ftp_upload.lrdevplugin +---helloworld.lrdevplugin +---languagefilter.lrdevplugin | +---mac | \---win +---metaexportfilter.lrdevplugin +---mymetadata.lrdevplugin +---mysample.lrwebengine | \---resources \---websample.lrwebengine +---resources | +---css | \---js \---strings \---en
ご覧の通り、リファレンスやマニュアルといったドキュメントと、サンプルコードだけで構成されています。
これだけで、どうやって開発するのか疑問に思われるかもしれませんが、EclipseやVisualStudiioのインストールが別途必要ということもありません。というのも、前提となる言語はLUAなので、適当なテキストエディタで開発でき、コンパイルやビルドといった作業も不要です。極論すればLRSDK6のリファレンスが全て頭の中に入っているならば、このSDK自体不要です。
Hello World
LUAスクリプトをLightroomのプラグインとして登録し、当該プラグインを実行することでLUAスクリプトが実行されるような仕組みとなっています。
サンプルのhelloworld.lrdevpluginをプラグインとして登録し、実行してみるとLightroomのダイアログ中に"Hello World"が表示されます。
マニュアルにも英文で書いてありますが、*.lrdevpluginというディレクトリ名で、内部にInfo.luaと、プラグイン本体となる任意名称のluaファイルの2つを最低限持った構造でプラグインを作成すればいいようです。
詳細はリファレンスとマニュアル(いずれも英語)をご参照ください。LUAそのものについては検索すれば日本語でもかなりの情報は集まります。
嵌った点
冒頭で記載した通り、私はホワイトバランスや露出を外部から操作したいと考えていました。その実現のために落とし込んだ処理形態は、設定値が記載されたCSVファイルを読み込んで現像設定に反映するというもの(逆にCSV出力も可能とする)。この実現にあたっては以下のような感じでした。
- CSVファイル入出力はLUAの標準のファイル入出力に加えて、文字列スプリット・結合用処理を自前で記述して実現
- LrDevelopController.setValue( param , value )で現像設定を変更することも普通にできた
- LrSelection.nextPhoto()が曲者
- nextPhoto()で処理対象ファイルを変更後、LrDevelopController.setValue( param , value )が効かない
- LrDevelopController.setValue( param , value )後にLrDevelopController.getValue( param )すると値は反映されているように見える
- だが、実際にGUI上で見える現像設定は変わっていない
- ダメじゃん \(^o^)/
- nextPhoto()で処理対象ファイルを変更後、LrDevelopController.setValue( param , value )が効かない
GUIで処理対象画像を変更した場合でも若干待たされることから、LrSelection.nextPhoto()後にウェイト的な処理を挟む必要があるのではないかと考えました。ですが、LUAにはsleepやwait的な関数は無いようです。そこで、LrTasksにsleep()があるのでそれを使おうと考えましたが、LrTask内の処理でないとsleepは使えないとランタイムエラーが発生します。で、sleepを使いたいがためだけに非同期処理としてLrTasks.startAsyncTask内に一連の処理を実装することで、LrTasks.sleep()が使えるようになりました。スリープ時間1.5秒を指定したら、期待通りの設定値変更が反映されるようになりました(それでも1800枚*1を処理対象とした場合、1800*1.5/60=45分もかかってしまう…)。処理対象ファイルが多い場合、スリープ時間は10秒程度にしないと私の環境では処理落ちするようです。
ということで、LrSelectionは使い勝手が悪いです。さらに、選択中画像(処理対象画像)の枚数を知る手段もないようで、何回ループ回せばいいのか判りません。仕方ないのでCSVファイルの行数分だけループ回すことにしました。が、CSVファイルがN行、選択画像がN-1枚だった場合、LrSelection.nextPhoto()が末端画像に達した後先頭に戻ってくるようで、先頭画像がCSVファイルのN行目の値で上書きされてしまう。といった有様で、運用に注意が必要な自分専用ツールとしての品質しか達成できていません。
LUAでまともにコードを書いたことが無い*2ことも取っつきにくさの一因ではありますが、まだまだSDKの機能を使いこなすのには時間がかかりそうです。
以上。