写真フォルダ分けマシンVer2.0
どうもNSZ山本です。
写真の整理ってみなさんはどうしてますか?
日付ごとに撮影した写真をフォルダ分けしておくと後で見返して思い出に浸るときに分かりやすくて良いです。
でも写真を管理する事は撮ることよりも労力がかかります。意外とほったらかしのときもあります。
手作業でフォルダ名を延々変換するのは面倒ですよね。
前回の実験によると1200枚の写真を手作業でフォルダ分けする場合15分もかかります。
困難です。人間のやる仕事じゃあありません。
撮影日を元に写真を自動でコンピューターがフォルダ分けしてくれたら楽なんだけどな。
自動化しよう。
Photo to Folder
というわけで手作りしました。
Photo to Folder Ver2.0(フォトトゥフォルダーバージョントゥ)
略称:P2F / PTF
仕組みとしては
メタデータの撮影日付から取得し、それをフォルダネームの日付をにします。
撮影日が撮影時点で狂っているケースを除けば、フォルダ分けの正確さは保証されます。
ダウンロード

dist.zipをダウンロードします。

200MBくらいあります。(重くてすまない)
解凍しておいてください。
使い方
前提

一眼レフの保存フォルダ構成は大体こんな感じのはずです。

フォルダの階層が図のようになっていることが前提になってます。
子階層OK(A)。自動で処理します。
同一フォルダに違う日付の写真が混在していても自動で分けてくれます。
一番上の所(C)に写真があるとわずかに消滅する可能性があるのでやめましょう(例外処理を一応したけど私は責任は負えません)
XXXの部分は、メーカーの毎で多少異なりますが以下のようなフォルダ名だと思います。
Cannon
- 100CANON
 - 101CANON
 - 102CANON
 
PENTAX
- 101_0101
 - 102_0102
 - 102_0103
 
Nikon
持って無いから分からないけど大体上と同じだと思う
……..
使い方

先程ダウンロードして解凍したものの中身です。
dist\ptf配下の
ptf.exeを押してください

名前を変更するフォルダを選択します。

どのフォルダのでもいいので中の写真をクリックして「開く」。
どの写真でも良いんですがとりあえず1枚目にしときます。
「開く」をクリック
※ウイルスバスターに攻撃扱いされる場合があります。このアプリを許可するをしてから再度ptf.exeを実行してください。

10秒以下。
デモは5つしかないので手作業でも可能な範囲ですが、
フォルダ数が100や1000や1万の場合だと話が変わってきます。機械なら一瞬でやってくれます。
同一フォルダに違う日付が混在していてもOK。ちゃんと分けてくれます。
ソースコード
windows用です。
linuxの場合このままだと使えません。unicode型をstr型に変換する処理が必要だったりします。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65  | 
						import os	 from PIL import Image	 from PIL.ExifTags import TAGS	 from pathlib import Path	 import tkinter.filedialog, tkinter.messagebox	 def getwd():	     root = tkinter.Tk()	     root.withdraw()	     fTyp = [("","*")]	     iDir = os.path.abspath(os.path.dirname(__file__))	     thisfile = tkinter.filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir)	     target_path = Path(thisfile).parent.parent	     target_path = str(target_path)+ "\\"	     return target_path	 def get_exif(img):	     exif = img._getexif()	     try:	         for id, val in exif.items():	             tg = TAGS.get(id, id)	             if tg == "DateTimeOriginal":	                 return val	     except AttributeError:	         return "NON"	     return "NON"	 def list_files(dir, func):	     for file in os.listdir(dir):	         try:	             img = Image.open(dir + file)	         except:	             continue	         datetimeinfo = func(img)	         img.close()	         yield (dir + file, datetimeinfo)	 def find_all_files(directory):	     for root, dirs, files in os.walk(directory):	         yield root	         for file in files:	             yield os.path.join(root, file)	 def main():	     cnt = 0	     target_path = getwd()	     fileal = find_all_files(target_path)	     for af in fileal:	         if os.path.isdir(af) and cnt!=0:	             af = af + "\\"	             for taginfo in list_files(af, get_exif):	                 path = taginfo[0]	                 name = Path(path).name	                 pathaft = Path(path).parent.parent	                 tag = taginfo[1].replace(":","")[:8]	                 os.renames(str(path), str(pathaft) + "\\" +tag + "\\" + name)	         cnt += 1	 if __name__ == '__main__':	     main()  | 
					
参考サイト
本当にありがとうございました。
→タプル型ってなんなんだ頭痛
Python2のstr/unicodeとencode/decode
Pythonで文字列を置換する:replace(), re.sub()
python – How to get absolute path of a pathlib.Path object? – Stack Overflow
→キャストみたいなやつ
Pythonで再帰的にファイル・ディレクトリを探して出力する
→感動した
WindowsでのPython外部モジュール導入のはまりどころ
→「プロセスはファイルにアクセスできません。別のプロセスが使用中です。」
何かインストールが足りない系