하위 폴더까지 조회해서 이동하는 거랑 실제 위치에서 실행 안되는 경우 파일을 찾을 수 없는 등의 오류가 있어 조금 변경해 보았다.
생각보다 속도도 빠른 편인듯.
참고로 pillow 패키지를 사용하는데 설치된 파이썬에 해당 패키지를 설치해야 하므로 아래와 같이 설치하고 진행한다.
python3 -m pip install pillow
Python 사진 자동 정리 프로그램 개발 - 참고 링크: https://hellojason.tistory.com/27
개선 내용
1. 하위 폴더 조회해서 이동할 건지 설정 : subfolder = False > True
2. 중복된 파일의 접두사 : duplicatePrefix = 'dup_'
3. 실행 위치에 따른 선택:
cur_dir = os.getcwd() # python 을 실행한 위치
cur_dir = ‘’ # 다른 곳에서 실행하지만 사진을 조회하고 실행하려는 위치
import os
import shutil
from PIL import Image
from PIL.ExifTags import TAGS
from datetime import datetime
# 디버그 모드 활성화 여부 - True, False
DEBUG = True
# 하위 폴더까지 확인하기
subfolder = False
# 이동하려는 곳의 파일이 존재한다면 추가하려는 앞자리
duplicatePrefix = 'dup_'
# 이미지 확장자
img_ext = ['.jpg', '.jpeg', '.JPG', '.JPEG', '.png', '.PNG', '.bmp', '.BMP']
# 영상 확장자
mov_ext = ['.mp4', '.MP4', '.avi', '.AVI', 'mts', '.MTS', '.m2ts', '.M2TS']
# 이미지 파일 저장 리스트
img_list = []
# 영상 파일 저장 리스트
mov_list = []
# 기타 파일 저장 리스트
etc_list = []
# 실행 현재 위치 - 하위 폴더 조회해서 모두 이동시켜 버림
# cur_dir = os.getcwd();
# 실행 위치(파일 검색하는 위치) 고정
cur_dir = '/Users/jymun/Desktop/Photo/PY_TestImage/'
# 디버그 모드 시작하기
if DEBUG :
print('img_list length : ', len(img_list))
print(f'current_dir : {cur_dir}')
# 이미지 날짜 정보 조회하기 - 함수
def getImageDate(image, DEBUG=False):
'''
이미지 EXIF 정보 읽기 - 이미지 생성 년, 월 리턴
'''
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:
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, DEBUG)
if DEBUG : print(img_date[0], img_date[1], img)
# 파일 위치 구분함
imgPath = img.split('/')
# 마지막 파일명을 반환
imgName = imgPath.pop();
# 파일명 앞 위치를 저장
imgOrgPath = ('/').join(imgPath);
if DEBUG : print(f'name= {imgName}, {imgOrgPath}')
# 새로운 폴더 위치 - 년도 / 월
dir_path = os.path.join(img_date[0], img_date[1])
# 원래 파일 위치
s_path = os.path.join(img)
# 이동하려는 폴더 위치 - 시작 위치를 기본으로 함
t_imgPath = os.path.join(cur_dir, dir_path);
# 이동하려는 폴더와 파일 위치
t_path = os.path.join(t_imgPath, imgName)
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(t_imgPath):
os.makedirs(t_imgPath)
# 년도/월 폴더와 파일이 재하는 경우 - (prefix : dup_ 추가)
if os.path.isfile(t_path) :
dup_name = duplicatePrefix + imgName
t_path = os.path.join(t_imgPath, dup_name)
# 파일 이동
shutil.move(s_path, t_path)
print(f'{img} ====> {t_path}')
count = count+1
print(f'{count} files moved!')
# 현재 폴더(하위까지 조회하기)
if subfolder:
for (root, directories, files) in os.walk(cur_dir):
for file in files:
file_path = os.path.join(root, file)
print(f' > file(s) Name: {file_path}')
if os.path.isfile(file_path):
name,ext = os.path.splitext(file)
if ext in img_ext:
img_list.append(file_path)
elif ext in mov_ext:
mov_list.append(file_path)
else:
etc_list.append(file_path)
else:
print(f'[{file_path}] is not File')
else:
# 현재 폴더만 조회하기
for file in os.listdir(cur_dir):
file_path = os.path.join(cur_dir, file)
if os.path.isfile(file_path):
name,ext = os.path.splitext(file)
if ext in img_ext:
img_list.append(file_path)
elif ext in mov_ext:
mov_list.append(file_path)
else:
etc_list.append(file_path)
else:
print(f'[{file_path}] is not File')
# 결과 조회
print('====== 최종 결과 ======');
print(f'Working Directory : {cur_dir}');
print(f'{len(img_list)} file(s) detected.')
# 최종 결과 확인
'''
if DEBUG:
print(f'img_list: {img_list}')
print(f'mov_list: {mov_list}')
print(f'etc_list: {etc_list}')
'''
# 실행
moveImageFiles(img_list, DEBUG)