テクノロジー · 実用ガイド
別フォルダーの JPEG 評価を darktable の RAW に引き継ぐ
日付別の RAW フォルダーと、その中の Jpgs サブフォルダーはそのままに。内容を確認できる計画を使って、明示的な星評価を既存の darktable サイドカーファイルに転記し、その変更をライブラリーへ読み込みます。

JPEG に評価を付けておくと、大量の写真を整理しやすくなります。ただし、対応する RAW が 1 つ上のフォルダーにあると、ひと手間必要です。写真の選別は済んでいても、現像したいファイルにはその判断が反映されていません。評価を引き継ぐためだけに、何年分ものフォルダーを整理し直す必要はないはずです。
このガイドでは、そのフォルダー構成に対応する補助プログラムを全文提供します。日付別フォルダーの中だけでファイルを対応付け、既存の RAW サイドカーファイルにある特定の評価フィールドだけを更新し、元のサイドカーファイルを保存します。その後、別の手順で darktable に読み戻すことで作業が完了します。まずは小さな日付別フォルダーで始め、すべての対応関係と結果を確認してから、アーカイブのほかの部分へ進んでください。
1. 対応付けを各日付別フォルダー内に限定する
対応する構成は、日付別フォルダーの直下に RAW があり、その中の Jpgs サブフォルダーの直下に JPEG があるものです。たとえば、Photos/2024/2024-05/Jpgs/DSC01234.JPG は Photos/2024/2024-05/DSC01234.ARW と対応します。評価の書き込み先は Photos/2024/2024-05/DSC01234.ARW.xmp です。
共通する拡張子を除いた名前は DSC01234 で、つづりも大文字・小文字も同じである必要があります。別の月のフォルダーにある DSC01234.ARW は別の候補であり、対応するファイルが見つからないときの代わりには使いません。補助プログラムは指定した写真フォルダーの階層をたどりますが、対応付けは必ずこの親子関係の中に限定されます。2 つのファイルが同じ撮影画像であることまでは判定しません。名前とフォルダー構成が、同じ写真の組であることを示しているかは、ご自身で確認してください。
既定値は ARW と Jpgs です。--raw-ext で別の RAW 拡張子を、--jpeg-subdir で別の子フォルダー名を完全一致で指定できます。同じ名前の JPEG が複数ある場合、対応する RAW 形式が複数ある場合、大文字・小文字の違いで対応が曖昧な場合、番号付きの編集バージョン用サイドカーファイルが存在する可能性がある場合は、処理を止めて確認対象にします。Jpgs の中にさらにあるサブフォルダーは、この対応付けの対象外です。
転記先のサイドカーファイルには、darktable のメタデータがすでに含まれている必要があります。補助プログラムは、欠けている編集履歴の代わりに空のファイルを作ったり、Lightroom 形式の DSC01234.xmp を推測して選んだりしません。darktable はインポート時に一部の別形式のサイドカーファイルを読めますが、darktable 標準のサイドカーファイル名には元画像の拡張子が残ります。この転記には、実際の標準形式のファイルを使ってください。
2. 正として扱う JPEG 評価の保存先を選ぶ
darktable で準備を始める前に、引き継ぎたい評価が現在どこに保存されているかを確認します。よくある状況は 3 つあり、補助プログラムで明示的に選べる参照元モードは 2 つですが、必要な準備はそれぞれ異なります。
評価が元の JPEG に埋め込まれている場合は、--rating-source jpeg を使います。その JPEG は変更しないでください。このガイドの参照元を準備するためだけに、JPEG をインポートしたり、JPEG サイドカーファイルを生成したりする必要はありません。補助プログラムは、明示的に保存された XMP-xmp:Rating を読み取ります。ほかのアプリケーションで表示される評価が、必ずこのフィールドに埋め込まれているとは見なしません。
引き継ぎたい JPEG の評価が現在 darktable のデータベースにある場合は、lighttable で対象の JPEG を選択し、history stack > write sidecar files を使ってサイドカーファイルを書き出します。現在の情報が Jpgs/DSC01234.JPG.xmp のような標準のサイドカーファイルに保存されます。darktable を終了してから、--rating-source sidecar を選びます。
既存の JPEG サイドカーファイルに引き継ぎたい評価がすでにある場合は、そのファイルを正として保持してください。前の段落の手順に従うためだけに、古い darktable データベースの内容で上書きしてはいけません。sidecar モードでは、同じフォルダーにある、JPEG の完全なファイル名に .xmp を付けたファイルが必要です。拡張子を除いた名前だけが同じ、短い名前のサイドカーファイルは探しません。
計画には、取得できた埋め込み評価とサイドカーファイルの評価の両方を記録します。両者が異なる場合は警告でその違いを示し、明示的に選んだ参照元モードを優先します。更新日時を比較して自動で決めることはありません。選んだ参照元に評価がない場合は、もう一方に評価があっても、その組をスキップします。情報がないことを 0 と見なさず、正しいモードを選んで新しい計画を作成してください。
3. 現在の RAW サイドカーファイルを準備して darktable を終了する
各転記先のサイドカーファイルが、RAW に残したい現在の編集状態を表していることを確認します。その編集内容が darktable のデータベースにある場合は、lighttable で対象の一群を選び、history stack > write sidecar files を使います。古いサイドカーファイルを再インポートする前に行ってください。RAW サイドカーファイルに使いたい新しい編集内容がすでにある場合は、古いデータベースの内容で上書きせず、計画作成に使うために保持します。適用後に、XMP からデータベースへ読み戻してください。
ライブラリーに本当に登録されていない RAW は、元の保存場所で import > add to library を使って追加し、その後、標準のサイドカーファイルが書き出されていることを確認します。JPEG のメタデータは、選んだ参照元の分岐で必要なものだけを準備してください。転記前に、重要なライブラリーデータとサイドカーファイルをバックアップしておきます。補助プログラムが後で作るバックアップの対象は、変更する RAW サイドカーファイルです。
終了する前に preferences > storage > XMP sidecar files を開き、look for updated XMP files on startup を有効にして、起動時に更新された XMP ファイルを探すようにします。この作業では、create XMP files を never ではなく on import に設定してください。after edit では、未処理の RAW すべてにサイドカーファイルがすでにあることは保証されません。
darktable を終了し、計画作成、確認、適用が終わるまで閉じたままにします。これらのファイルを書き換える可能性があるほかのアプリケーションも一時停止してください。準備した状態を維持するためです。画像が darktable に登録された後は、データベースの内容が優先され、外部で加えた XMP の変更を上書きすることがあります。

4. Python、RDFLib、ExifTool を準備する
Python 3.10 以降、RDFLib 7.6.0、ExifTool の実行ファイルが必要です。補助プログラムとマニフェストを置くために、新しい書き込み可能なフォルダーを用意します。例では python3 を使います。Windows で Python を py -3 で起動している場合は、一貫してそのコマンドを使ってください。
補助プログラムを実行するものと同じ Python 環境に RDFLib をインストールします。ほかのプロジェクトから分離するには、仮想環境が便利です。仮想環境を使う場合は、以下のすべてのコマンドで python3 をその環境の Python 実行ファイルに置き換えてください。
python3 -m pip install rdflib==7.6.0
python3 -c "import sys,rdflib; print(sys.version); print(rdflib.__version__)"
ExifTool は公式の配布元から入手し、インストール手順に従います。Windows では、コマンドラインで使うために exiftool(-k).exe を exiftool.exe に名前変更し、付属の exiftool_files フォルダーを同じ場所に置いてください。macOS または Linux でポータブル Perl 配布版を使う場合は、lib ディレクトリーを exiftool スクリプトと同じ場所に残し、Perl を利用できる状態にします。
ExifTool に PATH が通っていれば、補助プログラムは exiftool として見つけられます。そうでない場合は、--exiftool で実行ファイルのパスを指定してください。Windows なら --exiftool "C:/Tools/ExifTool/exiftool.exe" のように指定できます。macOS または Linux では実際の実行ファイルのパスを使います。この引数はファイルのパスであり、"perl exiftool" のようなシェルコマンドではありません。
計画の作成時と適用時には、同じ実行ファイルとバージョンを使ってください。その間に ExifTool を更新したり移動したりした場合は、記録された実行環境と一致するように、新しい計画を作成します。
5. 補助プログラムの全文を保存して確認する
次の段落には、補助プログラムの全文をコンパクトな 1 行の形式で収めています。段落全体をコピーし、作業フォルダー内の unpack_rating_helper.py というプレーンテキストファイルに保存してください。論理的には 1 行のままにします。エディター上の表示だけが折り返されるのは問題ありません。引用符、Markdown のコードフェンス、前後の記事本文を追加しないでください。
この展開用プログラムはオフラインで動作します。含まれているソースを展開し、SHA-256 を検証して、確認用の新しい sync_jpeg_ratings.py を、既存ファイルを上書きしない方法で作成します。補助プログラム自体を実行したり、何かをダウンロードしたりはしません。同名のファイルがすでにあれば、上書きを拒否します。
import base64,zlib,hashlib,sys; from pathlib import Path; data=zlib.decompress(base64.b64decode('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')); f=Path("sync_jpeg_ratings.py").open("xb") if hashlib.sha256(data).hexdigest()=='ba1136a7f667973bf1fef54682971bf964f4518825c99d45955ed871fdb88158' else sys.exit("SHA-256 mismatch; no helper file written"); f.write(data); f.close(); print("Created sync_jpeg_ratings.py for inspection; it has not been run.")
python3 unpack_rating_helper.py
使う前に、生成された sync_jpeg_ratings.py をテキストエディターで開いてください。復元されるファイルは 34,478 バイトで、SHA-256 は ba1136a7f667973bf1fef54682971bf964f4518825c99d45955ed871fdb88158 です。ハッシュが一致しない場合、補助プログラムは書き出されません。検証を外すのではなく、元の段落をコピーし直してください。
読みやすい形に展開されたプログラムは、既存の RAW サイドカーファイルの一時コピーにある XMP-xmp:Rating だけを変更します。RDFLib でそれ以外の RDF メタデータをすべて比較するため、意味が同じ XML の表記の違いは許容しますが、編集データの変更は許容しません。画像の画素を書き換えたり、darktable のデータベースにアクセスしたり、JPEG の XMP ブロック全体をコピーしたりはしません。
6. 計画を作成し、提案されたすべての組を確認する
最初は小さな日付別フォルダー 1 つ、または選んだ年のフォルダー階層で始めます。このコマンドの写真と ExifTool のパスを、ご自身のものに置き換えてください。既定の動作では、新しい JSON マニフェストを作成し、写真とサイドカーファイルは一切変更しません。
python3 sync_jpeg_ratings.py "/path/to/Photos/2024" --rating-source sidecar --manifest "ratings-plan.json" --exiftool "/path/to/exiftool"
JPEG に埋め込まれた評価を使う場合は、sidecar を jpeg に置き換えます。必要に応じて、適切な値で --jpeg-subdir "Jpgs" または --raw-ext ARW を追加してください。Windows で同じ処理を行うコマンドの完全な例は、次のとおりです。
py -3 sync_jpeg_ratings.py "D:/Photos/2024" --rating-source sidecar --manifest "ratings-plan.json" --exiftool "C:/Tools/ExifTool/exiftool.exe"
ratings-plan.json を開きます。まず counts を確認し、次に ready の各行にある jpeg、raw、raw_sidecar、rating_source、target_rating、new_rating を確認してください。パス、意図した変更前後の値、埋め込み評価とサイドカーファイルの評価が異なるという警告を、すべて確かめます。ドライランが正常に終わったからといって、すべての画像が適用可能とは限りません。
ready の組は適用対象です。unchanged の組は、すでに目的の値になっています。skipped の組は、選んだ参照元に明示的な評価がありません。blocked の組は確認が必要で、サイドカーファイルの欠落、不明な評価、ファイル名の競合、編集バージョンが存在する可能性、そのほかの未対応の条件などが理由として示されます。原因を解消してから、新しいマニフェストを作成してください。
計画には、ファイルの識別情報、更新日時、ファイル全体のハッシュ、関連する周辺のファイル名を記録します。RAW の画素は変更しませんが、大きな RAW のハッシュ計算には時間がかかります。扱いやすい規模のフォルダー階層を選んでください。計画が空の場合、選んだフォルダーに対応する Jpgs 子フォルダーがない可能性があります。アーカイブ内に評価付きの JPEG がないことの証明にはなりません。
7. 星なし、却下、既存の評価を意図的に扱う
参照元として受け付ける値は、-1 から 5 までの整数です。0 は明示的な星なしの評価で、-1 は明示的な却下です。フィールドがない状態は、どちらとも異なります。選んだ参照元に評価がない場合、補助プログラムは RAW の評価を維持します。読み取れない値、小数、範囲外の値、解釈が曖昧な評価は処理を止めます。
既定では、有効な参照元の評価を、評価がない転記先または評価が 0 の転記先に設定できます。同じ値なら変更しません。既存の評価が 1–5 または -1 で、参照元と異なる場合は保護します。参照元に合わせると 0 へ解除される場合も同様です。darktable の文書に記載された初回インポート時の評価の既定値は 1 なので、新しくインポートした RAW でも、この保護の対象になることがあります。
意図した転記のために既存の値を本当に置き換える必要がある場合は、対象の組を確認し、--replace-rated を付けて別の計画を作成してください。この設定は、その新しい計画全体のうち、条件を満たす評価の競合に適用されます。1 行だけを選ぶチェックボックスのように扱わず、適切に小さなフォルダー階層を使ってください。
python3 sync_jpeg_ratings.py "/path/to/Photos/2024" --rating-source sidecar --replace-rated --manifest "ratings-replace-plan.json" --exiftool "/path/to/exiftool"
その新しいマニフェストを確認してから適用します。処理を強行するために、JSON の値やステータスを手で編集しないでください。チェックサムが確認済みの計画を偶発的な変更から保護し、適用時には対応付け、参照元、競合時の方針、現在のファイルも確認します。置き換えオプションを使っても、不正な評価や曖昧なファイルの対応付けが許可されるわけではありません。
8. 確認済みの計画を適用し、処理記録を保管する
darktable を閉じたまま、確認したマニフェストそのものを適用します。ここで ratings-replace-plan.json を使うのは、その新しい置き換え計画を確認して承認した場合だけです。ExifTool のパスも前と同じものを使ってください。
python3 sync_jpeg_ratings.py --apply "ratings-plan.json" --exiftool "/path/to/exiftool"
書き込みの前には毎回、選んだ評価を読み直し、計画に記録したファイルとディレクトリー内のファイル一覧を検証します。元の RAW サイドカーファイルは、マニフェストの隣にある、重複しない rating-sync-backup-<plan-id> フォルダーに保存します。その中の sidecars には、転記先の相対フォルダーパスを維持します。receipt.json には、各転記先、そのバックアップ、変更前後の評価、ハッシュが記録されます。
ExifTool は、作業用のサイドカーファイルで、名前空間を指定した 1 つの評価フィールドを変更します。続いて補助プログラムが評価と、評価以外の RDF データ全体を確認し、入力の状態を再確認してから転記先を置き換えます。置き換え後のサイドカーファイルを検証し、RAW、JPEG、記録対象となった JPEG サイドカーファイルが、それぞれ記録済みのフィンガープリントと引き続き一致することを確認します。XML の書式やツールキットの識別子は変わることがありますが、バックアップには元のバイト列が残ります。
ファイル、関連するファイル名の一覧、またはマニフェストが変わっていた場合は、古い状態に基づく処理を停止します。一括処理の途中でエラーが起きると、それ以前に完了した組は完了したままになり、それ以降の組は未着手になります。処理記録の result_counts と unattempted_ready_pairs を確認してください。これは個々の変更を順に確定する処理であり、一括で全部成功するか全部取り消すかの処理ではありません。
committed_verification_failed または commit_state_requires_inspection に注意してください。これらは、現在のファイルを記録されたハッシュと照合する必要があることを示します。置き換え後のエラーは、何も変更されなかったことを意味しません。中断時には、最後に保存された prepared の記録も確認が必要です。マニフェスト、処理記録、バックアップは一緒に保管してください。
重複しないバックアップディレクトリーによって、同じ計画をそのまま 2 回実行することを防ぎます。停止した一括処理の問題を解消したら、残りの作業用に新しい計画を作ってください。この保護を回避するために、以前のバックアップディレクトリーを削除してはいけません。処理記録が完了を示していても、darktable_reload はまだ pending です。
9. サイドカーファイルを darktable に読み込み、結果を確認する
darktable を起動します。更新されたサイドカーファイルのダイアログで、対象の RAW を選び、XMP の内容をデータベースへ読み込む keep the XMP edit を選択してください。古いデータベースの状態をサイドカーファイルへ戻す keep the database edit は選ばないでください。これらのボタン名は現在の公式ソースで確認していますが、バージョンや翻訳によって表記が異なることがあります。
想定した項目が一覧に出ない場合は、転記が失敗したとも成功したとも決めつけないでください。起動時の確認は、設定とタイムスタンプに依存します。代替手順として、lighttable の import > add to library を使います。元の RAW フォルダーに移動し、select only new images のチェックを外したうえで、この一括処理の対象となる既存の RAW ファイルを明示的に選択してください。このチェックボックスが制御するのは最初の選択状態です。チェックを外すだけでは、対象ファイルを選択したことにはなりません。追加操作を完了して、XMP データを読み直します。
ファイルは元の場所のまま使ってください。copy & import は別のインポート経路を使い、既存のサイドカーファイルを同じ方法では利用しません。画像を登録解除したり削除したりする必要はありません。refresh exif は元画像を読み直すため、評価を上書きすることがあります。また、JPEG のサイドカーファイルを RAW の履歴スタックとして読み込むと、編集内容が置き換わることがあります。どちらも、この転記の読み戻し手順ではありません。
RAW に表示される星、却下の状態、元の編集内容を確認します。利用しているカスタムの並び順も確認してください。カスタム並び順の位置情報は XMP に保存されないため、サイドカーファイルを保持しても、データベースにしかないすべての情報を復元できるとは限りません。その状態が重要な場合は、データベースのバックアップを保管してください。
その後の編集を行う前に、確認済みの転記を 1 件だけ元に戻すには、darktable を終了し、処理記録から正確に対応する raw_sidecar と backup の組を探します。バックアップを backup_sha256 と、現在のサイドカーファイルを new_sidecar_sha256 と照合してください。次の読み取り専用コマンドは、ファイルの SHA-256 を表示します。実際のパスを 1 つずつ入れて実行してください。
python3 -c "import hashlib,sys; print(hashlib.sha256(open(sys.argv[1],'rb').read()).hexdigest())" "/full/path/to/sidecar.xmp"
現在の転記先が記録された転記後のバージョンとまだ一致している場合は、ファイルマネージャーで、その 1 件の元のバックアップを、正確に対応する RAW サイドカーファイルへ上書きコピーします。その後、復元したサイドカーファイルを darktable に読み込んで確認してください。適用後に現在のファイルが変更されている場合は、何かを復元する前に、そのファイルを別に保存し、その後の編集内容を調べます。関係のない転記先には触れないでください。現在の一括処理の評価と編集状態を確認してから、次の日付別フォルダーへ進みます。
検証について:提供する補助プログラムは、Python 3.12、RDFLib 7.6.0、ベンダー配布版 13.59.3 の ExifTool 13.59 を使った、27 件の完全な CLI テストに合格しました。テストには、生成した JPEG、編集履歴を含む合成の darktable 形式 XMP、内容を解釈しない RAW の代用ファイルを使っています。意図した評価の変更、画像のバイト列と評価以外のメタデータが変わらないこと、バックアップ、競合、古くなった入力、一部だけの完了、対象を 1 件に限定した意図的な復元を確認しました。展開用プログラムも 4 件の復元テストに合格しています。Python の最適化を有効にしてもハッシュ検証は働き、既存の出力ファイルは上書きしません。これらの結果には、darktable の GUI/データベースへの読み戻し、実際のカメラ RAW のデコード、複数プラットフォームでの実行は含まれません。画面操作の説明は公式の 5.6 マニュアルと現在のソースで確認しています。最終結果は、ご自身のライブラリーで検証してください。