何をやっているか
Pythonの画像処理モジュールPillowを使って指定したフォルダ内の写真のをリサイズして、右下にロゴマークを合成して保存する、というプログラムを作っています。
ここまでの進捗
以下コードで横向きの写真にロゴの挿入ができました。ここからさらに進化させたいと考えております。
Python
1import os 2import sys 3import shutil 4from datetime import datetime 5from enum import Enum, auto 6 7import tkinter, tkinter.filedialog 8from PIL import Image 9 10WM_FILE = 'logo.png' #横写真の場合のウォーターマーク画像 11 12class Mode(Enum): 13 BLG = auto() #ブログ用 14 15def mkdir_dto(img, output_dir_path): 16 """画像の撮影日のフォルダを作成する 17 :param img: 画像(PIL) 18 :param output_dir_path: 出力先のフォルダーのパス 19 :return: 作成したフォルダーのパス 20 """ 21 EXIF_DTO = 36867 #Exifの撮影日のタグ番号 22 23 # 移動先フォルダー作成。フォルダー名はExifの撮影日からyyyymmdd形式で生成 24 exif = img._getexif() 25 dt = datetime.strptime(exif[EXIF_DTO], '%Y:%m:%d %H:%M:%S') 26 output_sub_dir = dt.strftime('%Y%m%d') 27 output_path = os.path.join(output_dir_path, output_sub_dir) 28 os.makedirs(output_path, exist_ok=True) 29 30 return output_path 31 32def make_img(img, img_name, mode, watermark, output_path): 33 """画像をリサイズし、ウォーターマークを貼り付け、別名で保存する 34 :param img: 画像(PIL) 35 :param img_name: 画像(PIL)ファイル名 36 :param mode: Mode.BLGならブログ用、Mode.TMBならサムネイル用 37 :param watermark: ウォーターマーク画像(PIL) 38 :param output_path: 出力先フォルダーのパス 39 """ 40 BLG_CHAR = '_s' #ブログ画像のファイル名に付加する文字列 41 MAX_W_BLG = 4000 #ブログ画像の幅の上限 42 MAX_H_BLG = 2400 #ブログ画像の高さの上限 ※こちらはあまり意味のない数値です 43 44 # サイズ、ファイル名の末尾に付加する文字列を設定 45 if (mode == Mode.BLG): #ブログ用 46 w, h = MAX_W_BLG, MAX_H_BLG 47 add_chr = BLG_CHAR 48 49 else: 50 return None 51 52 #リサイズ 53 img.thumbnail((w, h)) 54 55 #ウォーターマークを付加 56 w_img, h_img = img.size 57 w_wm, h_wm = watermark.size 58 img.paste(watermark, (3000, 300), watermark)#ロゴの位置 59 60 #ファイル名に文字列を付加して保存 61 fname, ext = os.path.splitext(img_name) 62 img.save(os.path.join(output_path, fname + add_chr + ext), quality=95, exif=img.info['exif'])#追記 63 64 65# ウォーターマーク画像読み込み 66watermark = Image.open(WM_FILE) 67 68#元画像フォルダー選択 69root = tkinter.Tk() 70root.withdraw() 71msg = '画像フォルダーを選択してください。' 72img_dir_path = tkinter.filedialog.askdirectory(title=msg) 73if (not img_dir_path): #[キャンセル]クリック時の処理 74 print('フォルダーを選んでください。') 75 sys.exit() 76 77#出力先フォルダー選択 78msg = '出力先フォルダーを選択してください。' 79output_dir_path = tkinter.filedialog.askdirectory(title=msg) 80if (not output_dir_path):#[キャンセル]クリック時の処理 81 print('フォルダーを選んでください。') 82 sys.exit() 83 84# 元画像フォルダー内のファイル1つずつ処理 85for img_file in os.listdir(img_dir_path): 86 #元画像読み込み (PIL) 87 img_path = os.path.join(img_dir_path, img_file) 88 img_pil = Image.open(img_path) 89 90 #ファイルの移動先フォルダー作成 91 output_path = mkdir_dto(img_pil, output_dir_path) 92 93 #ブログ用画像とサムネイル用画像を作成 94 make_img(img_pil.copy(), img_file, Mode.BLG, watermark, output_path) 95# make_img(img_pil, img_file, Mode.TMB, watermark, output_path) 96 97 #元画像(PIL)を閉じる 98 img_pil.close()
どう進化させたいか&発生しているエラー
こちらのプログラムに、写真のEixf情報を元に縦写真か横写真かの判別をして横写真ならロゴを右下に、縦写真なら270°回転させたロゴを右上に合成する、という機能を追加したいです。
自分なりに考えて、画像処理の部分にExifの回転に関する情報を取得して条件分岐させるというプログラムを書きましたが、
'Image' object has no attribute '_getexif'
というエラーになってしまいます。
Python
1def make_img(img, img_name, mode, watermark, output_path): 2 """画像をリサイズし、ウォーターマークを貼り付け、別名で保存する 3 :param img: 画像(PIL) 4 :param img_name: 画像(PIL)ファイル名 5 :param mode: Mode.BLGならブログ用、Mode.TMBならサムネイル用 6 :param watermark: ウォーターマーク画像(PIL) 7 :param output_path: 出力先フォルダーのパス 8 """ 9 EXIF_ROT = 274#Exifの回転のタグ番号 10 exif = img._getexif() 11 BLG_CHAR = '_s' #ブログ画像のファイル名に付加する文字列 12 MAX_W_BLG = 4000 #幅の上限 13 MAX_H_BLG = 2400 #高さの上限 14 15 # サイズ、ファイル名の末尾に付加する文字列を設定 16 if (mode == Mode.BLG): #ブログ用 17 w, h = MAX_W_BLG, MAX_H_BLG 18 add_chr = BLG_CHAR 19 20 else: 21 return None 22 23 #リサイズ 24 img.thumbnail((w, h)) 25 26 #ウォーターマークを付加 27 _orientation = exif[EXIF_ROT] 28 w_img, h_img = img.size 29 w_wm, h_wm = watermark.size 30 31 if _orientation == 1: 32 img.paste(watermark, (3000, 300), watermark)#ロゴ位置は仮です 33 34 elif _orientation == 6: 35 img.paste(watermark, (2800, 2000), watermark, ROTATE_270)#ロゴ位置は仮です 36 37 elif _orientation == 8: 38 img.paste(watermark, (400, 2000), watermark, ROTATE_90)# ロゴ位置は仮です 39 40 41 #ファイル名に文字列を付加して保存 42 fname, ext = os.path.splitext(img_name) 43 img.save(os.path.join(output_path, fname + add_chr + ext), quality=95, exif=img.info['exif'])# 44
条件分岐の手前のExif情報を取得するやり方が間違っているのでしょうか?
小生の力不足で恐縮ですが、解決方法があればご教授いただければ幸いです。
回答1件
あなたの回答
tips
プレビュー