子供が生まれて写真が膨大な量になってきたこともあり、
「サブスクで管理するには高い!!! でも、子供の写真を消すことができない!!」
ということで、家庭用NASを導入することにした。
そこで今まで取っていた写真をGoogleフォトから家庭用NASに写真を写真を移そうと思ったのだが、すべてのデータをダウンロードしたところなんとメタデータと写真が別に保存されている仕様!
しかも、写真に撮影日などの情報を再度付けるプログラムがあるらしいけど、なんかexeしかなくて、Macユーザーの私は一体どうすればいいのー!
このままでは写真を取った日付けがわからなくなって移行したはいいもののなんか微妙な感じになってしまう!
というわけでしょうがないのでpythonでtimestampの書き換えプログラムを書いたのでここに備忘録を残しておきます。
ちなみにアーカイブ形式での一括ダウンロード方法はこちらを参考にしてください。
環境構築
dokcer compose
にて環境構築を行う。
$ cd .env_files
$ docker compose up -d
まあただのpython環境でも実行可能だと思うので、それでもOK。
解凍したアーカイブファイルの中身
こちらを参考にダウンロードしたアーカイブ形式のファイルを解凍したときの中身はこんな構造。
$ tree
.
├── Google フォト
│ ├── アルバム名
│ │ ├── IMG_2439.JPG
│ │ ├── IMG_2439.JPG.json
│ │ ├── IMG_2440.JPG
│ │ ├── IMG_2440.JPG.json
.
.
.
JPGのメタ情報を見てみると、ダウンロードした日が作成日になっている。
この写真は明らかに5年以上前に取った写真なのだが、作成日が今日になっている。
そこで、同じファイル名のjsonファイルの中身を見ると。
{
"title": "IMG_6248.JPG",
"description": "",
"imageViews": "0",
"creationTime": {
"timestamp": "1561986860",
"formatted": "2019/07/01 13:14:20 UTC"
},
"photoTakenTime": {
"timestamp": "1561986555",
"formatted": "2019/07/01 13:09:15 UTC"
},
"geoData": {
"latitude": 0.0,
"longitude": 0.0,
"altitude": 0.0,
"latitudeSpan": 0.0,
"longitudeSpan": 0.0
},
"geoDataExif": {
"latitude": 0.0,
"longitude": 0.0,
"altitude": 0.0,
"latitudeSpan": 0.0,
"longitudeSpan": 0.0
},
"url": "https://url_to_googlephoto.com",
"googlePhotosOrigin": {
"mobileUpload": {
"deviceType": "IOS_PHONE"
}
}
}
jsonファイルの中にメタデータが書き込まれているよう。
なのでjsonファイルから読み取ったデータをもとに写真(PNG)のメタデータを書き換える。
コード
まずは、対象ファイルのtimestampを取得する。
def get_timestamp(file):
#作成日時を取得
ct_u=os.path.getctime(file)
ct_d=datetime.fromtimestamp(math.floor(ct_u))#日時表記に変換
#更新日時を取得
mt_u=os.path.getmtime(file)
mt_d=datetime.fromtimestamp(math.floor(mt_u))
#アクセス日時を取得
at_u=os.path.getatime(file)
at_d=datetime.fromtimestamp(math.floor(at_u))
return ct_d, mt_d, at_d
次に、JSON形式のファイルから情報を読み込む。
def read_json(metadata_json):
# jsonファイルの読み込み
with open(metadata_json) as f:
d = json.load(f)
return d
そしてファイルの情報を書き換える。
def set_timestamp(file:str , ctime:float, atime:float):
# アクセス日時 と 更新日時 を変更
os.utime(path=file, times=(ctime, atime))
def chage_timestamp(metadata_json):
'''
jsonファイルの情報に合わせてタイムスタンプを書き換え
'''
# 格納されているディレクトリを取得
dirname = os.path.dirname(metadata_json)
# json読み込み
d = read_json(metadata_json)
# 入力形式に変更
ctime = float(d["photoTakenTime"]["timestamp"])
mtime = float(d["creationTime"]["timestamp"])
# 対象ファイルを取得
target_file = os.path.join(dirname, d["title"])
set_timestamp(target_file, ctime, mtime)
最後に格納されたすべてのJSONファイルに処理をかける。
def change_timestamp_in_target_dir(target_dir):
json_files = glob.glob(os.path.join(target_dir, "**", "*.json"))
for json_file in tqdm.tqdm(json_files):
chage_timestamp(json_file)
実行方法
src/
内にあるtimestamp.pyを実行する。
引数に対象にしたい画像ファイル名を指定すると、指定した名前と同じjsonファイルを読み込んでメタ情報を書き換える。
$ python timestamp.py /work/test_file/IMG_6248.JPG
before
(datetime.datetime(2024, 2, 10, 0, 14, 46), datetime.datetime(2024, 2, 9, 15, 20, 5), datetime.datetime(2024, 2, 10, 0, 14, 47))
<change timstamp>
after
(datetime.datetime(2024, 2, 10, 0, 27, 17), datetime.datetime(2019, 7, 1, 13, 14, 20), datetime.datetime(2019, 7, 1, 13, 9, 15))
実行した結果の写真がこちら
ちゃんと作成日が変更された!!
結論
クラウドからデータを移したりすると色々面倒なのがわかった。
まあ(お金のためには)そんなことのにも負けてられないので、技術力で乗り切ることにしょう!
こちらでソースコードを公開していますので、参考にしてもらえると幸いです。
https://gitlab.com/sontyu/timestamp.git