15

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?

Gaurav Vichare
  • 1,093
  • 1
  • 10
  • 24

4 Answers4

19

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.

oulenz
  • 1,120
  • 1
  • 13
  • 22
Joachim
  • 411
  • 6
  • 13
  • 6
    piexif.insert() adds a 2nd EXIF block if one already exists. A better way would be : exif_dict = piexif.load(filename); piexif.remove(filename); ... ; piexif.insert(exif_bytes, filename). Google Photos always reads the 1st EXIF block, other softwares display the last one. Better to have only one EXIF block in the JPEG. – Eric H. Nov 12 '20 at 11:15
6

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.

Mark Setchell
  • 169,892
  • 24
  • 238
  • 370
  • 25
    This is a question how to do it in Python. – Peter Wood Oct 09 '15 at 08:26
  • 6
    @PeterWood Yes, I know. The OP may think some lengthy script is required and may only know Python and therefore have tagged it as such. I am merely pointing out a far simpler solution - if OP wishes to ignore it, he is welcome.... else he could spend 3 days writing Python and say *"If only someone had mentioned I could do it in 5 seconds with a one-liner"*. Just trying to help. – Mark Setchell Oct 09 '15 at 08:30
  • You could clarify that with a question in the comments. I appreciate you are very helpful. I also try to be helpful. – Peter Wood Oct 09 '15 at 08:42
  • 8
    Except I was searching for "python add date taken exif", this is one of the top results, and it's completely not helpful to me – autonomy Sep 13 '18 at 14:53
  • @MarkSetchell I'm trying to use your solution in this thread and could use your advice! [https://stackoverflow.com/questions/60514748/changing-jpg-date-taken-to-be-5-hours-before-existing-value] (https://stackoverflow.com/questions/60514748/changing-jpg-date-taken-to-be-5-hours-before-existing-value) – zemken12 Mar 03 '20 at 20:38
2

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

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-\d\d\d\d\d\d\d\d-WA\d\d\d\d.*", f) and not re.match(r"^IMG-\d\d\d\d\d\d\d\d-WA\d\d\d\d-ANIMATION.gif", f):
                print(f+" Matched")
                match = re.search("^IMG-(\d\d\d\d)(\d\d)(\d\d)-WA\d\d\d\d.*", 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__")
1

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_\d\d\d\d\d\d\d\d-\d\d\d\d\d\d.*", f):
                match = re.search("^Screenshot_(\d\d\d\d)(\d\d)(\d\d)-(\d\d)(\d\d)(\d\d).*", 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]) 
wjandrea
  • 23,210
  • 7
  • 49
  • 68
angristan
  • 539
  • 6
  • 17