カテゴリ:Python・画像処理
「元の写真は縦向きなのに、Pillowで保存したら横向きになった」。
すでにPillowで画像を処理しているなら、保存前にEXIFの「向き」を反映しているか確認します。この記事は、動いている処理へ追加する箇所の説明です。
1 写真は、表示するときだけ回転していることがある
JPEGには、画像データとは別に「この向きで表示してほしい」という情報が入ることがあります。対応するアプリは、その情報を使って写真を表示します。
読み込んで保存する処理で向き情報が引き継がれないと、見た目が変わる場合があります。すべてを90度回転させる前に、元画像の向き情報を確認しましょう。
2 画像を開いた後、リサイズや保存の前に追加する
JPEG1枚をImage.openなどで開き、imageという変数に入れている場合の修正例です。
【追加するコード】
from PIL import ImageOps
corrected = ImageOps.exif_transpose(image)
【コードここまで】
imageは、すでに開いている画像です。自分のコードでimなど別の名前を使っていれば、その変数名に合わせます。既存処理の中へ入れる場合は、周りと同じ字下げにしてください。
この後のリサイズや保存にもcorrectedを使います。元のimageを保存し続けると、向きを反映した結果が使われません。
この2行だけでは、ファイルへの保存も、上書きの防止も行いません。まず原本のコピー1枚で試し、後段の保存先には別の新しい名前を指定します。既存ファイルへ保存しないことと、原本が別に残っていることを確認してください。
3 向き情報を反映するとどう変わるか
比較には、向きの違いが分かる試験用の色画像を使います。「処理前」は向き情報を反映していない画像データ、「処理後」は向き情報を反映して保存したJPEGを読み直した結果です。
左:処理前の画像データ(向き情報未反映)
右:向き情報を反映し、別名保存したJPEGの表示用画像
この例はOrientationが6のJPEGです。矢印と文字が読める向きになることを確認しました。検証環境はPython 3.12.14/Pillow 12.3.0です。
普段のアプリでは、元画像が最初から正しい向きに見えることがあります。アプリが向き情報を反映しているため、この「処理前の画像データ」と同じ表示になるとは限りません。
4 この方法で直せること・判断できないこと
元の向き情報は、開いたimageに対して次の1行で確認できます。274はOrientationを示す番号です。
print(image.getexif().get(274))
・Orientationが2〜8:情報に合った回転や反転を画像データへ反映します。
・Orientationが1:補正不要という情報なので、画像データの向きは変えません。
・None:向き情報がないため、写真の内容から正しい上下を推測することはできません。
向き情報そのものが間違っていれば、処理後も意図した向きにならない場合があります。変わらなかった画像へ同じ処理を繰り返す前に、元画像と向き情報を見直してください。
5 保存後に、向きと画質を確かめる
JPEGで保存し直すと、再圧縮で画質や容量が変わることがあります。無劣化の回転や、撮影情報をすべて残す処理としては扱いません。
元のEXIFをそのまま保存に使い回すと、補正前の向き情報まで付け直してしまう場合があります。撮影日時や色プロファイルなどを残したい場合も、向きの補正とは別に、後段の保存設定を確認します。
新しい画像を開き、意図した向きか、画質に問題がないかを確かめてから利用してください。今回は静止JPEG1枚の例です。PNG、HEIC、TIFF、複数フレームや大量の一括処理の手順は、ここでは扱いません。
参考:Pillow公式ドキュメント
画像の向き情報
ImageOps.exif_transpose
JPEGの保存設定
EXIF情報の読み取り