画像のトリミングと回転などコマンドで一括にを書いているときに、exifに埋め込まれたサムネイルを作り直したり、メタデータの値を修正したり確認したりする必要が生じました。
Exiftranでexifを考慮した画像の回転はできますし、別の画像処理ソフトでトリミングなどの加工したあとでExiftranを使ってやるとexifを自動で整えることができます。
ただ、exifを正しく設定しないカメラ、スキャナや画像処理ソフトの間違いを細かく訂正するにはexiv2も必要です。
manで調べると、jpg画像を劣化させることなく回転させるもので、同目的のjpegtranに比べて、自動で orientation tag を元に回転させることができ、必要に応じて orientation や dimension(画像サイズ)を更新し、さらに埋め込みのサムネイルも同時に回転させるとあります。
トリミングをしなくてよいなら、Exiftranだけで前回の目的は一発で達せられます。
orientation tag に従ってフォルダ内の全jpg画像を自動回転する
exiftran -ai *.jpg
ファイルが一つのときは別の名前のファイルにすることができる
exiftran -o outputfile.jpg -a inputfile.jpg
フォルダ内の全jpg画像にexifのサムネイルを追加(更新)する
exiftran -gi *.jpg
元のファイルを直接書き換える(inplace)オプションなのでfor...などがいらない。もちろん-oで出力を指定するのと組み合わせてfor...を使うこともできる。バックアップファイルを作る選択肢もある。
自動でOrientationに従う回転(-a)したときも、回転角を指定して回転したときも、Orientationはクリア(値は1:top-left)される。Orientationの記述がない場合は追加されないが、この場合の値は1が仮定されるので問題ない。また、exifのdimension(画像サイズ)が実際と異なる場合には修正される。
回転は本来のデータの向きに対して実行されるので、本来画像がどちらを向いていたのか正しく把握していないと混乱する。スキャナで向きを指定した時とか、カメラを水平に構えた時など、間違ったOrientationが記録されたときは、注意する必要がある。
下に一覧にしたが exiftran でexif情報を表示するのは、
exiftran -d 対象ファイル名
だが、Pixel X Dimension, Pixel Y Dimension の値は、exiftran以外のソフトでは変更されずに生成時のままになっていることがある。また、ここで -d はdumpの意味だが、他のソフトでは delete の意味であることが多いので注意。
man Exiftran で表示される英語のマニュアルは平易・簡潔で読みやすい。
transform options: | |
-a | orientation tag に従って自動回転 |
-9 | 時計回りに90度回転 |
-1 | 時計回りに180度回転 |
-2 | 時計回りに270度回転 |
-f | 上下反転(flip) |
-F | 左右反転 |
-t | 左上\右下に沿って反転(transverse) |
-T | 左下/右上に沿って反転 |
-nt | thumbnailを回転しない |
-ni | imageを回転しない |
-no | orientation tag を更新しない |
-np | don't pare lost edges 8の倍数に切り詰めない |
other options: | |
-h | このhelpを表示して終了 |
-d | exif data の出力(dump) |
-c <text> | コメントタグをtextに新規作成または更新 |
-g | (re)generate thumbnail 「サムネイルを作り直す」 |
-o <file> | 出力ファイル名の指定 |
-i | inplace(元のファイルを書き換える) |
-b | バックアップファイル(backup)を作る(-iの時) |
-p | タイムスタンプを元のまま(Preserve)とする(-iの時) |
exiftranだけでは、変更前にOrientationやthumbnailがどうなっているかが、はっきりしないことがある。
ファイルマネージャや画像閲覧のソフトではサムネイルを独自に生成することが多く、exifのthumbnailを使わないのが普通。これを確認できるよいソフトが見つからなかった。
Orientationについてもファイルマネージャや画像閲覧のソフトて自動で回転表示をするものもあるので、実際のデータがどうなっているかがわからない。特に、exifを正しく設定しないカメラ、スキャナや画像処理ソフトで乱れているものについては、大抵の場合は無視されるのだが、不具合を生じることもある。調査する道具が必要。
Exif の他、IPTC, XMPのメタデータや画像コメントも読み書きするプログラムとあります。カメラメーカーのメーカーノートと呼ばれる独自のタグもある程度は読み取ることができ、以前頼りにしたことがあります。
man exiv2 で表示されるマニュアルは長く、読みにくいので、よく使いそうな例だけ示します。
-psオプションでファイル名だけを指定すると、概略を表示します。exif以外にもファイル名や、実際の縦横のピクセル数も一緒に表示するので助かります。実はこの-psはデフォルトで、省略可能です
exiv2 -ps ファイル名
このようになります。
adachi@ebook:xjpg$ exiv2 crroEPSON002.jpg File name : crroEPSON002.jpg File size : 5155072 Bytes MIME type : image/jpeg Image size : 3412 x 2415 ⇦実際のピクセル数 Camera make : SEIKO EPSON CORP. Camera model : EP-881A Series Image timestamp : ……省略…… Image quality : Exif Resolution : 2480 x 3507 ⇦exif上のピクセル数 White balance : Thumbnail : image/jpeg, 13237 Bytes Copyright : Exif comment :
上の例はexifを書き換えない処理ソフトで、トリミングをして90度回転をしたのでピクセル数が異なっています。Orientationは残念ながら-psオプションでは表示されません。-paか-peで表示されます。
-paや-peオプションで多数の項目が表示されますが、次のようにすれば必要なものだけが表示されます。
adachi@ebook:xjpg$ exiv2 -g Dimension -g Orien DSC_5650.JPG Exif.Image.Orientation Short 1 top, left Exif.Photo.PixelXDimension Long 1 5568 Exif.Photo.PixelYDimension Long 1 3712
-g は grep の意味で、続く文字列が含まれるものが出てきます。
残念ながら今度は-psで出てきた実際のピクセル数を出す方法がありません。
exifの中に入っているthumbnailは規格によれば、160x120の小さいものです。
exiv2 -ep ファイル名.jpg
ファイル名-preview1.jpg ができます。
adachi@ebook:xjpg$ exiv2 -ep DSC_5650.JPG adachi@ebook:xjpg$ ls -l DSC_5650* -rw-rw-r-- 1 adachi adachi 17216 7月 1 02:19 DSC_5650-preview1.jpg -rw-rw-r-- 1 adachi adachi 2927963 7月 1 00:27 DSC_5650.JPG
実際には256x188のものでした。このthumbnailはカメラが撮影のときに作ったものです。exiftranに作らせると160x117になりました。
adachi@ebook:xjpg$ exiv2 -pp DSC_5650.JPG Preview 1: image/jpeg, 256x188 pixels, 17216 bytes adachi@ebook:xjpg$ exiv2 -pp DSC_5650wt.JPG Preview 1: image/jpeg, 160x117 pixels, 8456 bytes
-ep の代わりに -et でも同じサムネイルが、ファイル名-thumb.jpg でできます。しかし、exiftranの回転操作で埋め込まれたサムネイルも回転した場合、-et だと .tif 形式になることがあります。
-Mオプションはexifの値をファイルにセットします。
exiv2 -M"set Exifの項目名 値" ファイル名
例えば Orientation の値を 1 にセットするには次のようにします。
adachi@ebook:xjpg$ exiv2 -g Orientation DSC_5523.jpg Exif.Image.Orientation Short 1 right, top adachi@ebook:xjpg$ exiv2 -M"set Exif.Image.Orientation 1" DSC_5523.jpg adachi@ebook:xjpg$ exiv2 -g Orientation DSC_5523.jpg Exif.Image.Orientation Short 1 top, left
前後の操作はOrientationの値が変化したことを確かめただけで、本体は-Mのある行だけです。
-mを使うとテキストファィルからたくさんの値をまとめてセットできます。
全部のメタデータを消去
exiv2 -da ファイル名
サムネイルだけを消去
exiv2 -dt ファイル名
ある項目だけを消去というのは、見当たりません。現在の全部の設定値をテキストファイルに書き出して、編集して、全消去したファイルに書き戻すという手順になるのだと思います。
あるいは-Mなどを使って、値を当たり障りのないものに書き換えるという手もあります。たとえばOrientationならば1にすると消去したのと同等な意味になります。
もう少し拾っておきます。
基本形は、
exiv2 [options] [action] file ...
この...が意味するところは、対象となるファイルを列記できる、つまり *.jpg も使えるということ。
[action]については以下の表によるが、[options]の記述で明確になっている場合は省略可能とある。実際、ほとんどの場合使わない。せっかく作ったので置いておく。
action | 説明 |
---|---|
pr | print | メタデータの出力。これがデフォルトのaction |
ex | extract | メタデータの抽出。*.exv, *.xmp, *.jpg(image files) |
in | insert | *.exv, *.xmp, *.jpg からのメタデータの挿入 |
rm | delete | メタデータの削除 |
ad | adjust | exifタイムスタンプの書き換え |
mo | modify | メタデータの変更。追加と削除も |
他 | mv, fi, fc |
actionをほぼ必要としないので、次のオプションが大切。
Option | 長い書き方 | 説明 |
---|---|---|
-u | unknownタグ(名前のないタグ)を含める。(実は-psと同じデータが出る) | |
-d tgt | --delete | tgtで指定した種類のタグを削除する。 |
-e tgt | --extract | Extract target(s) for the 'extract' action. |
-g key | --grep | 指定した文字列を含むキーのみを表示する。-gを複数書くことで or の働きをする。 |
-K key | --key | 指定したキーを表示する。-bの完全一致版。-K Exif.Photo.DateTimeOriginal などと指定する。複数指定可 |
-m file | --modify | どのキーにどの値を設定するかのコマンドを入れたファイルを指定して、一度に追加や書き換えを行う |
-M cmd | --Modify | コマンドを直接書いて追加や更新を行う |
-p mode | プリントモード。exifの一覧の出し方を選択する。 s:概要(デフォルト) a:Exif,IPTC,XMP e:Exif t:Exifタグの翻訳 p:可能なプレビュー一覧 |
|
-P flg | exifの一覧でタグなどの出し方を事細かに指定する。 k:キー n:タグ名 y:タイプ c:要素数 s:バイト数 v:値 t:解釈値 |
cmd, flg, tgt は次のように指定する
cmd set | add | del key [[type] value] setは既存のタグからkeyに合致するものをvalueに書き換える。または追加する。 addはタグを追加する。タグの重複を妨げない。 delはkeyのみ指定。存在するタグを消去する。 typeを指定しなければ、それぞれのkeyにより仮定されたものを使う。 valueは残りの行の終わりまでと解釈されるが、'value'または"value"とクォーテーションマークで括ってもよい flg E | I | X | x | g | k | l | n | y | c | s | v | t | h Exif, IPTC, XMP, num, grp, key, label, name, type, count, size, vanilla, translated, hex ここでvanilla は「普通の」つまりtranslateしないplaneな値 tgt a | c | e | i | p | t | x | C | X | XX | - all, comment, exif, iptc, preview, thumb, xmp, ICC Profile, SideCar, RawXMP, stdin/out
Exif.Image.Orientation は画像のデータをそのままに、どの向きで表示すべきかを示すタグである。
JPEGのデータの規格に後付に決められたものなので、ハードもソフトも考慮するものとしないものがある。
exifの値は1〜8の数値で、exiv2は translated と指定すると top,left などと表示する。戻す操作との一覧を次に示す。戻す操作はさまざまあるので一例を示した。正しい向きをどの様に変化させた図かというのと混同すると混乱するので注意。
値 | translated | 意味 | 戻す操作(例) |
---|---|---|---|
1 | top, left | 上辺を左から右へ | そのまま |
2 | top, right | 上辺を右から左へ | 左右反転 |
3 | bottom, right | 下辺を右から左へ | 180度回転 |
4 | bottom, left | 下辺を左から右へ | 上下反転 |
5 | left, top | 左辺を上から下へ | 左右反転、時計まわりに270度回転 |
6 | right, top | 右辺を上から下へ | 時計まわりに90度回転 |
7 | right, bottom | 右辺を下から上へ | 左右反転、時計まわりに90度回転 |
8 | left, bottom | 左辺を下から上へ | 時計まわりに270度回転 |
画像のデータはファイルの中ではひとつながりになった情報の列になっている。これで二次元の画像を復元するとすれば、文字の列がページを埋めていくように、紙の1辺の端から1行を埋めていき、1行が埋まったら2行目に進むという手順を踏むはず。
最初の1行が上下左右のどの辺から始まるかと、行内でどちら側から埋めていくかの2つの情報で図の向きを指定することができます。
辺の選択肢は top, bottom, left, right のどれかで、辺が topかbottom なら 開始点はleftかright、 辺がleftかright なら 開始点はtopかbottom とそれぞれ2択なので、全部で8通りあるわけです。
Orientationの値を考慮して表示する例を示します。A, B, C の例は皆赤い矢印の向きにデータが並んでいるものとします。
A | top, left の例。指定がなければこれです。 上から始めて左から右に描いていきます。 |
|
B | Aと同じデータを right, top で表示した例です。 データの保存順はそのままにして、表示を回転することができます。 |
|
C | right, top で正しい向きに表示される例です。 このデータはAと同じではありません。 NRという文字をAのように正しい向きで表示するには、 right, top の指定に従ってデータを配置すればよいことがわかります。 |
ここでも画像データは赤矢印の向きに保存されているとします。表の左「Orientation指定なしの画像」は指定をつけなかった場合やOrientationを処理しないソフトウェアによる表示の様子です。
表の右「Orientationの値を指定した画像」はOrientationを処理した場合の表示です。
top,rightなどの処理がうまく働くことと、回転や反転で正しい向きにする操作を確認できます。
値 | Orientation 指定なしの画像 |
translated 意味 (正しい向きにする操作例) |
Orientation の値を指定した画像 |
---|---|---|---|
1 | top, left 上辺を左から右へ (そのまま) |
||
2 | top, right 上辺を右から左へ (左右反転) |
||
3 | bottom, right 下辺を右から左へ (180度回転) |
||
4 | bottom, left 下辺を左から右へ (上下反転) |
||
5 | left, top 左辺を上から下へ (左右反転後、時計 まわりに270度回転) |
||
6 | right, top 右辺を上から下へ (時計まわりに90度回転) |
||
7 | right, bottom 右辺を下から上へ (左右反転後、時計 まわりに90度回転) |
||
8 | left, bottom 左辺を下から上へ (時計まわりに270度回転) |
ひょっとしたら「書かれたNRの文字の上部(つまりはRの丸い方)にNからRの向きに矢印をかけばtranslated表記になっている!」と思いませんでしたか。残念ながら6,8が違います。
一般的なデジタルカメラで縦位置の写真を撮ると、右手を下に構えると6のright,top、右手を上に構えると8のleft,bottomになります。逆さまにして写した場合、3のbottom,rightになるのが筋ですが、そうならないカメラもあります。
スマートフォンでは撮影したスマートフォンで閲覧するならすべて1のtop,leftでよいと思いますが、横長の位置で撮ると6や8が付き、縦長に持って表示すると回転して縮小表示されるという腑に落ちない状態になる場合もあります。機種によっては予約値(1〜8以外は勝手に使ってはいけない)のはずの0を入れるものもあるようです。
カメラやスキャナのデータの他、加工ソフトで処理したものの現状を確認するために用いた方法です。
Orientation関係だけに興味がある場合は、次のが有効です。
adachi@ebook:imgorg$ exiv2 -g Orien -g Dimension DSC_1873.JPG Exif.Image.Orientation Short 1 top, left Exif.Photo.PixelXDimension Short 1 5568 Exif.Photo.PixelYDimension Short 1 3712
これは exiv2 -pa で設定されている出力から3つのキーについての値を抽出したものです。3項目の"1"は多分shortの値がひとつ分という要素数なので、Orientationのplaneな値ではないです。
そこで、-P を使って項目を入れ替えます。-Pkvt はkey,vanilla,translated です。
adachi@ebook:imgorg$ exiv2 -Pkvt -g Orient -g Dimension DSC_1873.JPG Exif.Image.Orientation 1 top, left Exif.Photo.PixelXDimension 5568 5568 Exif.Photo.PixelYDimension 3712 3712 adachi@ebook:imgorg$ exiv2 -Pkvt -g Orient -g Dimension DSC_1874.JPG Exif.Image.Orientation 8 left, bottom Exif.Photo.PixelXDimension 5568 5568 Exif.Photo.PixelYDimension 3712 3712 adachi@ebook:imgorg$ exiv2 -Pkvt -g Orient -g Dimension DSC_1875.JPG Exif.Image.Orientation 6 right, top Exif.Photo.PixelXDimension 5568 5568 Exif.Photo.PixelYDimension 3712 3712 adachi@ebook:imgorg$ exiv2 -Pkvt -g Orient -g Dimension DSC_1877.JPG Exif.Image.Orientation 1 top, left Exif.Photo.PixelXDimension 5568 5568 Exif.Photo.PixelYDimension 3712 3712
1,8,6,3と並ぶはずが、最後は1に戻っています。このカメラは逆さに構えたときも3にはなりません。XDimension,YDimensionの値が同じなので、カメラを横位置で構えてもデータのスキャンの向きには影響はなく、Exif.Image.Orientationだけで済ませていることがわかります。
そして当然ながら、カメラでは2,4,5,7の反転を伴う状況は生まれません。
3のbottom, right になるカメラもあります。
adachi@ebook:imgorg$ exiv2 -Pkvt -g Orient -g Dimension P5030004.JPG Exif.Image.Orientation 3 bottom, right Exif.Photo.PixelXDimension 4608 4608 Exif.Photo.PixelYDimension 3456 3456
このスマートフォンは撮影時の構え方によってXDimension,YDimensionの値が入れ替わっています。この場合Orientationの値は1でいいのですが、なんと0になっています。
adachi@ebook:imgorg$ exiv2 -Pkvt -g Orient -g Dimension IMG_20200503_140545.jpg Exif.Image.Orientation 0 (0) Exif.Photo.PixelXDimension 2336 2336 Exif.Photo.PixelYDimension 4160 4160 Exif.Thumbnail.Orientation 0 (0) adachi@ebook:imgorg$ exiv2 -Pkvt -g Orient -g Dimension IMG_20200503_140607.jpg Exif.Image.Orientation 0 (0) Exif.Photo.PixelXDimension 4160 4160 Exif.Photo.PixelYDimension 2336 2336 Exif.Thumbnail.Orientation 0 (0)
まずは回転と反転の操作を整理して名前をつけておきます。ここでの操作は元に戻す操作ではなく、元の画像がどのように変換されるかに注目しています。
「なにもしない」という「操作」も加えています。名前は数学の習慣で"e"としています。
変換名 | e | σ1 | σ2 | σ3 | τ1 | τ2 | τ3 | τ4 |
---|---|---|---|---|---|---|---|---|
変換操作 | なし | |||||||
変換結果 | ||||||||
exiftran | -9 | -1 | -2 | -F | -T | -f | -t |
σ(シグマ)は書き方から回転をイメージしています。添字の1,2,3は90度回転を何回行うかということです。4で元に戻るので3までしかありません。
τ(タウ)はシグマの次の文字であることと、文字の形が鏡映の雰囲気を醸していることからこれにしました。添字の1,2,3,4は反転する軸を縦線から始めて時計回りに45度ずらすたびに+1しています。5以上は同じ反転の繰り返しになります。
図形の回転と反転(鏡映)には連続して行うと他の操作と同等の効果が得られるということがあります。exif-Orientationの元に戻す操作も異なる組み合わせ(と順序)で書かれている場合があります。
ここでは変換の組み合わせを一覧にしておきます。
⇩x2\x1⇨ | e | σ1 | σ2 | σ3 | τ1 | τ2 | τ3 | τ4 |
---|---|---|---|---|---|---|---|---|
e | e | σ1 | σ2 | σ3 | τ1 | τ2 | τ3 | τ4 |
σ1 | σ1 | σ2 | σ3 | e | τ2 | τ3 | τ4 | τ1 |
σ2 | σ2 | σ3 | e | σ1 | τ3 | τ4 | τ1 | τ2 |
σ3 | σ3 | e | σ1 | σ2 | τ4 | τ1 | τ2 | τ3 |
τ1 | τ1 | τ4 | τ3 | τ2 | e | σ3 | σ2 | σ1 |
τ2 | τ2 | τ1 | τ4 | τ3 | σ1 | e | σ3 | σ2 |
τ3 | τ3 | τ2 | τ1 | τ4 | σ2 | σ1 | e | σ3 |
τ4 | τ4 | τ3 | τ2 | τ1 | σ3 | σ2 | σ1 | e |
表の上に並べた変換(x1⇨)を先に行い、左に並べた変換(⇩x2)を後にすると、交点の操作と同等になるように書いてあります。適用する操作の順番で結果が違いますから注意が必要です。式で表現する場合は後に適用する操作を左に追加していくので x2x1 と書きます。
たとえば、exif-orientationの 5 left-top は元に戻す方法に「左右反転、時計まわりに270度回転」とありますが、
τ4 = σ3τ1
と書きます。この操作を逆にすると
τ2 = τ1σ3
になります。
また、表から2つ組み合わせて τ4 となるのは、たくさんあることがわかります。
τ4 = σ3τ1 = σ2τ2 = σ1τ3 = τ1σ1 = τ2σ2 = τ3σ3