study/프로그래밍

python_ 이미지의 잘못된 촬영일자 정보를 파일명 기준으로 일괄변경

밥짓는사나이- 2022. 3. 26. 01:21
728x90

episode.

사건발생..

우리아이의 어린이집 사진을 대량으로 받고 NAS에 올리고 보니,

이런..

촬영일자가 엉망진창이다. 그나마 시간은 맞는데 날짜들이 1년전, 한달전 뭐 이런식이다..

 

촬영일자는 중요한것 같다. 아이는 하루하루 다른데, 한달씩 1년씩 날짜가 안맞게 되면, 사진속 우리아이의 추억을 진실로 느끼기가 어렵다. 그래서 날짜가 중요한데...

그래도 다행인건 사진의 파일명에 날짜정보와 일련번호(20200101-0001)로 이뤄져있다. 그래 이걸 쓰면 되겠다.

사진에는 EXIF라는 메타데이터가 있는데, 이를 바꿀수 있는 툴이 많다. 하지만.
내가 원하는 방식은 없다... 시간을 일정기간 미루거나, 일정기간 당기거나,
일정날짜시간으로 변경하거나... 이런...오랜만에 ...코딩을 결심한다..

 

우리는 exif 패키지를 사용할거고, 그안에 있는 메타데이터의 DateTime에서 추출한 시간정보와  파일이름에서 추출한 날짜정보를 조합하여 DateTime 에 업데이트 하고자한다.

 

일단 사용할 패키지를 import 합니다.

from datetime import datetime
from exif import Image
import os


두개의 함수를 만들고, 활용할건데요.
첫번째는 우리가 사용할 파일들의 경로/파일 리스트를 받아올 함수인 get_image_path 를..
두번째 함수는 날짜를 변경해줄 change_exif_date함수입니다.
마지막으로 main 함수에 path기반으로 날짜를 변경하는 함수로 준비했습니다.

 

첫번째 get_image_path입니다.

- 입력: root_dir 이미지 파일들이 있는 디렉토리

- 출력: result_list 파일의 경로들을 담은 리스트 

def get_image_path(root_dir):
    result_list = []
    for (root, dirs, files) in os.walk(root_dir):
        print("# root : " + root)
        if len(files) > 0:
            for file_name in files:
                file_path= os.path.join(root, file_name)
                result_list.append(file_path)
    return result_list

 

두번째 get_image_path입니다.

- 입력

  . img_path: 이미지경로

  . new_prefix: 새로저장할 폴더의 prefix, 기존 폴더에 prefix를 넣어 저장하도록 하였습니다.

  . img_filename: 날짜를 뽑아내기위한 파일명

- 출력: 구지 필요는 없으나, 변경내용을 확인하고자 넣었어요. 

  . img_datetime : 이미지의 기존 촬영일자

  . new_img.get("DateTime") : 변경된 촬영일자

def change_exif_date(img_path,new_prefix_path,img_filename):
    with open(img_path, 'rb') as img_file:
        img = Image(img_file)
    # Original datetime that image was taken (photographed)
    print(img,img.has_exif)
#     print(img,img.list_all())
#     print(f'-----{img.DateTime}')
#     print(img.get("datetime_original"))
    if img.has_exif:
        if img.get("datetime_original"):
            image_datetime = img.get("DateTime")

        else:
            img.DateTime = '2020:09:14 00:00:00'
            img.datetime_original = '2020:09:14 00:00:00'
            image_datetime = img.DateTime

    else:
        img.DateTime = '2020:09:14 00:00:00'
        img.datetime_original = '2020:09:14 00:00:00'
        image_datetime = img.DateTime
    
    ## image_datetime None check
    
    if image_datetime ==None:
        img.DateTime = '2020:09:14 00:00:00'
        img.datetime_original = '2020:09:14 00:00:00'
        image_datetime = img.DateTime
    

    print(f'DateTime -before: {image_datetime}')


    ## check dash or not
    glue = image_datetime[4]
    print(glue)

    # Update
    new_date= img_filename[:4]+glue+img_filename[4:6]+glue+img_filename[6:8]+" "+image_datetime[-8:]
    print(new_date)
    # img.DateTime = datetime.strptime(new_date, "%Y:%m:%d %H:%M:%S")
    # new_DateTime = datetime.strptime(new_date, "%Y:%m:%d %H:%M:%S")
    img.DateTime = new_date
    img.datetime_original = new_date

#     print(new_DateTime)
    with open(f'{new_prefix_path}{img_path}', 'wb') as new_img:
            new_img.write(img.get_file())
    
    with open(f'{new_prefix_path}{img_path}', 'rb') as new_img_file:
            new_img=Image(new_img_file)
        
            
    print(f'newdate_time : {new_img.get("DateTime")}')
    print(f'saved {new_prefix_path}{img_path}')
    return image_datetime, new_img.get("DateTime")

이미지에 촬영일자가 없기도하고, 각각의 이미지마다 촬영일자 정보의 연/월/일 구분이 dash(-) 또는 : 로 발견되어, 기존 촬영일자 정보의 형식대로 변경할수있도록 준비했어요..

 

마지막 main 입니다.

디렉토리 설정후, 각함수를 호출하여 변경작업을 합니다.

def main():
    ## directory 설정, root_dir: 변경할 이미지 폴더, new_dir: 변경후 이미지폴더의 prefix
    root_dir = "image/"
    new_dir = "result_"
    ## get_image_path
    file_paths = get_image_path(root_dir)

	# file_paths
    for file_path in file_paths:
        print(f'---start -----{file_path}------')
        file_type = os.path.splitext(os.path.basename(file_path))[1]
        print(file_type)
        if file_type =='.jpg':   ## 중간에 mp4 동영살 파일이 있어서 이럴경우 skip합니다.
            file_name = os.path.splitext(os.path.basename(file_path))[0]
            b_image_date, a_image_date = change_exif_date(file_path,new_dir,file_name)
            print(f'{file_path} 완료, before : {b_image_date},  after :{a_image_date}')
            
        else:
            print('pass, it is not a jpg file')

 

요렇게해서 수GB짜리 대량의 일년간의 이미지를 변경했어요.
사실 코딩에 소질도 없고, 잘 못하지만,, 제기록을 위해 남겨둡니다.

728x90
728x90