pythonで全JPEG画像のExif情報を消す
pythonでちょっとしたツールを作ることが趣味みたいになってきていますが、今回も作りました。gulp(タスクランナー)でできそうですが、しっくりくる情報がなかった&python慣れのため作成。
Exif自体についてやその他の対処方も少し記載したので参考まで。
(背景)撮影写真の「カメラの向き」が、imgタグ表示に支障
スマホやデジタルカメラで撮影したJPEG画像には「Exif情報」という撮影時の記録が含まれています。この情報には「カメラの向き」も含まれており、問題は下記の厄介な仕様。
・PC上のアプリケーションやブラウザで画像単体をプレビューする場合、実は「カメラの向き情報」が考慮され自動回転表示されるため「本来の画像の向き」に気が付きにくい
・一部ブラウザを除き、imgタグでの表示ではExif情報は考慮されないため、プレビューで見ていた向きと異なり(本来の画像の向きで)表示される
・windowsの画像プロパティから消せるExif情報の中に方向は含まれてない
(画像はInpulse Adventureより。向きと反転情報が1-8の数字で格納されている。)
通常はアプリケーションを通す際にExif情報は消されたり(Photoshopでいうメタデータ)、SNS等WEBサービスやCMSではアップロード時に処理されるので問題になりにくいですが自らが構築したサービスであったり、通常のimgタグに撮影写真をそのままアップロードして表示させる際に気を付ける必要があります。
向き以外にも撮影機材やら日時やら公開を意図しない情報も含まれている点にも注意。
(対処方法)
・事前にアップロードする画像のExif情報を削除し、向きも補正しておく
・フロントサイド側でjs(exif.js等)で向き情報取得、それに基づきcanvasタグ等に画像表示
(imgタグだと縦横のサイズが変わりレイアウトに支障出る可能性あり)
・サーバー側で処理させる
基本的にいずれかで対処することになりますが、私の場合知見があるのはせいぜいフロントサイドまで&既に出来上がっているHTML構造から変更を加えたくない状況を想定して、そもそもの画像情報からexifを削除するプログラムを作成しました。
(作ったもの)全jpg画像のExif情報を消す
サイト全体など、階層化されて保存されているファイル群の中で、jpg画像だけを対象にExif情報を消していくプログラムです。相変わらず拙いですがこちら。exif削除と、ファイル選定をそれぞれ関数にしています。
こうして方向含むExif情報を削除することで、本来の向きがわかります。
# coding: UTF-8
#!/usr/bin/python3
import os
from PIL import Image
def exif_delete(path):
with Image.open(path) as src:
data = src.getdata()
mode = src.mode
size = src.size
with Image.new(mode, size) as dst:
dst.putdata(data)
dst.save(path)
print('>>>>> Exif in ' + path + ' deleted.')
def image_check(path):
for pathname, dirnames, filenames in os.walk(path):
for filename in filenames:
if filename.endswith('.jpg') or filename.endswith('.JPG'):
exif_delete(os.path.join(pathname,filename))
while True:
project_dir = input('Enter project direction:').replace('"','').strip()
if os.path.exists(project_dir):
os.chdir(project_dir)
image_check(project_dir)
print('>>>>> Exif deletion accomplished.')
break
else:
print('>>>>> No directory found, try again.')
(使ったもの)画像処理ライブラリpillow
画像のあらゆる処理に対応したライブラリで、exif情報については本来の使い方から逸れているかもしれませんが、扱えるので採用。下記を参考にしまいた。今回はしていないですが、たぶんexifの方向に応じて回転処理させることもできると思います。
(工夫したこと)os.walkで全ディレクトリ走査
os.walkで現在のディレクトリ、内包するディレクトリ、内包するファイルを引っ張り出し、forでそれぞれに処理を与えるまさに「走査」させました。
globモジュールを併用してもできそうですので下記参考まで。
以上です!何かすこしでも役に立てば嬉しいです。
コメントもお待ちしてます。
この記事が気に入ったらサポートをしてみませんか?