핸드폰/디카로 사진 촬영하는 일은 이제 일상이 되었습니다.
Google Photo 를 사용하면 간편하지만, 비용도 문제고 과거 파일도 업로드해야하고, 용량이 크면 비용도 문제가 됩니다.
저도 NAS에 아이 과거부터 있던 사진만 수만장이 되는데, 한 폴더에 넣고 찾기 편하게 관리했더니 폴더가 느려져서 문제가 생기고 역시 사진 찾기도 어려웠습니다.
수만장 사진 파일을 어떻게 정리할지 고민하다..
촬영 년/월로 자동으로 정리해 주는 프로그램을 만들어 보았습니다.
이미지 정리 규칙
촬영한 년>월 형태로 디렉토리(폴더)를 만들고 자동으로 파일을 옮겨줍니다.
동일한 파일명이 있으면, "dup_" 파일명을 수정해서 이동합니다. (혹시나 동일 파일명으로 이전파일을 삭제 하지 않도록)

알고리즘
- 작업 디렉토리의 이미지 파일 목록 확인
- 이미지 메타 정보(EXIF)로, 촬영일시를 확인 (클릭)
- 이미지 촬영일로 년/월 디렉토리 생성
- 이미지 파일 이동 ( 중복인 경우 파일명 수정후 이동 )
소스 프로그램
GitHub - jasonbaek97/photo_arrange
Contribute to jasonbaek97/photo_arrange development by creating an account on GitHub.
github.com
#-*- coding: utf-8 -*-
import os
import shutil
from PIL import Image
from PIL.ExifTags import TAGS
from datetime import datetime
img_ext = ['.jpg','.jpeg','.JPG','.png','.bmp'] # 이미지 확장지
video_ext = ['.mp4','.avi','.mts','.m2ts','.MTS'] # 비디오 확장자
DEBUG = False
img_list = []
video_list = []
etc_list =[]
cur_dir = os.getcwd()
if DEBUG :
print('img_list length : ',len(img_list))
print(f'current_dir : {cur_dir}')
def getImageDate(image,DEBUG=False):
'''
이미지 EXIF 정보를 읽어, 이미지 생성 년,월 return
:param image(str)
:return img_date(list)
'''
img = Image.open(image)
img_date = []
if DEBUG : print(img.filename)
# exif 정보로 이미지 촬영일 체크
img_info = img._getexif()
if img_info is not None:
for tag_id in img_info: # exif TAG 정보에서 촬영일 체크
tag = TAGS.get(tag_id, tag_id)
data = img_info.get(tag_id)
if tag == 'DateTime' or tag == 'DateTimeOriginal': # 촬영일 존재하면 년,월 세팅
data = data.replace('-',':') # '-' 일자 구분자를 :로 변환
# meta정보 고려해서 10자리 끊고 -> 빈칸 0 trim후 0 채워넣기
data = data[:11] # yyyy:mm:dd 10자리만 읽기
data = data.replace(' ','0') # 공백 '0' 채움
date = data.split(':') # date = [년, 월, 일]
if DEBUG: print(f'Data : {data}, Date : {date}')
try:
img_date.append(date[0])
img_date.append(date[1])
except:
print('!!!!!! ERRROR !!!!!!!!!')
print(f'img name : ', image)
print(f'data : {data}')
print(f'date : {date}')
img_date[0] = 'error' # 강제 error 세팅
img_date.append('00') # 두번째 값 '00' 추가
print(f'img_date : {img_date}')
if DEBUG:
print(f'{tag:25}: {data}')
# EXIF 값이 없으면, 파일 생성일 세팅
if len(img_date) == 0 :
date = datetime.fromtimestamp(os.path.getctime(image)).strftime('%Y:%m:%d').split(':')
img_date.append(date[0])
img_date.append(date[1])
if(DEBUG):
print(f'date : {date}')
print(f'img_date : {img_date}')
return img_date
def moveImageFiles(img_list, DEBUG=False):
count =0
img_cnt = len(img_list)
print(f'Target file count : {img_cnt}')
for img in img_list:
img_date = getImageDate(img)
if DEBUG : print(img_date[0], img_date[1], img)
dir_path = os.path.join(cur_dir, img_date[0], img_date[1])
s_path = os.path.join(cur_dir, img)
t_path = os.path.join(dir_path, img)
if DEBUG:
print(f'dir_path : {dir_path}')
print(f'Source_path : {s_path}')
print(f'Target_path : {t_path}')
# 이미지 년\월 디렉토리 존재하면, 파일을 이동하고 없으면 생성 후 이동
if not os.path.exists(dir_path):
os.makedirs(dir_path)
# 해당 폴더에 동일파일 존재 시 이름 변경 (prefix : dup_ 추가)
if os.path.isfile(t_path) :
dup_name = 'dup_'+ img
t_path = os.path.join(dir_path, dup_name)
shutil.move(s_path, t_path)
print(f'{img} ====> {t_path}')
count = count+1
print(f'{count} files moved!')
'''
현제 디렉토리의 이미지,비디오,기타 파일 목록 확인
'''
for file in os.listdir(cur_dir):
if os.path.isfile(file):
name,ext = os.path.splitext(file)
if ext in img_ext:
img_list.append(file)
elif ext in video_ext:
video_list.append(file)
else:
etc_list.append(file)
else:
print(f'[{file}] is not File')
print('========== report ===========')
print(f'Working Directory : {cur_dir}')
print(f'{len(img_list)} file(s) detected.')
if DEBUG:
print(f'img_list : {img_list}')
print(f'video_list : {video_list}')
print(f'etc_list : {etc_list}')
moveImageFiles(img_list)
실행결과
480개 정도의 파일을 테스트 해봤는데, 잘 작동합니다.

위 프로그램으로 실제 NAS 서버에 python 설치하고, contab 형태로 10분 단위로 작업을 실행해 주었습니다.
저는 이제 휴대폰 사진을 찍으면 NAS로 자동 upload 되고 10분이네, 자동 년/월로 정리가 됩니다.
이후 AI 객체 검출 (Object Detection)을 추가하여 특정 이미지(내가 있는 사진, 음식, 자동차 등)를 자동으로 찾는것도 만들어 볼 생각입니다.
'Language' 카테고리의 다른 글
[JS] 비동기 (Async) 호출 방식 이해하기 Callback , Promise (0) | 2024.08.03 |
---|---|
[Python] 해쉬 문제 - 달리기 경주 (Programmers) (0) | 2023.08.10 |
[Python]이미지 메타정보(EXIF)로 촬영일시 찾기 (0) | 2022.12.18 |
[Python] 디렉토리 내 파일 목록 리스트 (0) | 2022.11.16 |
[Python] 일정 시간 (초)마다 실행 (0) | 2022.10.25 |