How to Change image captured date in python?

Question:

I have over 500 images (png /jpg) having wrong captured date (Date taken) because of wrong camera date settings. I moved photos to mobile and mobile gallery sorts photos on the basis of ‘Date Taken’. I want all photos to be displayed in order.

So how can I change captured date (Date taken) using python script?

Asked By: Gaurav Vichare

||

Answers:

No real need to write Python, you can do it in one line in the Terminal using jhead. For example, adjust all EXIF times forward by 1 hour

jhead -ta+1:00 *.jpg

Make a COPY of your files and test it out on that first!

Download from here.

Answered By: Mark Setchell

This is quite easy to do using the piexif library:

from datetime import datetime
import piexif

filename = 'image.jpg'
exif_dict = piexif.load(filename)
new_date = datetime(2018, 1, 1, 0, 0, 0).strftime("%Y:%m:%d %H:%M:%S")
exif_dict['0th'][piexif.ImageIFD.DateTime] = new_date
exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = new_date
exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = new_date
exif_bytes = piexif.dump(exif_dict)
piexif.insert(exif_bytes, filename)

This script will insert the new date 2018:01:01 00:00:00 into the DateTime, DateTimeOriginal and DateTimeDigitized EXIF fields for image.jpg.

Answered By: Joachim

I might be late to this party, but i wrote a python script for bulk changing taken time field for whatsapp photos based on filename format Eg: IMG-20160117-WA0001.jpg.
Also this does not overwrite the existing properties. https://github.com/dsouzawilbur/Scripts/blob/master/Change_Photo_Taken_Time.py

from datetime import datetime
import os
import re
import piexif

def absoluteFilePaths(directory):
    for dirpath,_,filenames in os.walk(directory):
        for f in filenames:
            fullPath = os.path.abspath(os.path.join(dirpath, f))
            if re.match(r"^IMG-dddddddd-WAdddd.*", f) and not re.match(r"^IMG-dddddddd-WAdddd-ANIMATION.gif", f):
                print(f+" Matched")
                match = re.search("^IMG-(dddd)(dd)(dd)-WAdddd.*", f)
                year = match.group(1)
                month= match.group(2)
                day = match.group(3)
                exif_dict = piexif.load(fullPath)
                #Update DateTimeOriginal
                exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = datetime(int(year), int(month), int(day), 4, 0, 0).strftime("%Y:%m:%d %H:%M:%S")
                #Update DateTimeDigitized               
                exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = datetime(int(year), int(month), int(day), 4, 0, 0).strftime("%Y:%m:%d %H:%M:%S")
                #Update DateTime
                exif_dict['0th'][piexif.ImageIFD.DateTime] = datetime(int(year), int(month), int(day), 4, 0, 0).strftime("%Y:%m:%d %H:%M:%S")
                exif_bytes = piexif.dump(exif_dict)
                piexif.insert(exif_bytes, fullPath)
                print("############################")


absoluteFilePaths("__DIRECTORY_WITH_PHOTOS__")
Answered By: Wilbur Dsouza

PNG does not support EXIF so I made this to fix the creation/modification time instead, based on Wilbur Dsouza‘s answer:

import datetime
import os
import re
import sys
import time

import piexif


def fix(directory):
    print(directory)
    for dirpath, _, filenames in os.walk(directory):
        for f in filenames:
            fullPath = os.path.abspath(os.path.join(dirpath, f))
            # Format: Screenshot_20170204-200801.png
            if re.match(r"^Screenshot_dddddddd-dddddd.*", f):
                match = re.search("^Screenshot_(dddd)(dd)(dd)-(dd)(dd)(dd).*", f)
                year = int(match.group(1))
                month = int(match.group(2))
                day = int(match.group(3))
                hour = int(match.group(4))
                minute = int(match.group(5))
                second = int(match.group(6))

                date = datetime.datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second)
                modTime = time.mktime(date.timetuple())

                print(f, date)

                os.utime(fullPath, (modTime, modTime))


if __name__ == "__main__":
    fix(sys.argv[1]) 
Answered By: stan
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.