Nikitenko Maxim (Sets88)

Personal page

Python - Photo renamer

I had a dream, to rename all my photos from personal photo archive into names kind of "Year_month_day_hour_minute.jpg" instead of "IMG09123.jpg", which is not so informative, my variant is very handy, it'i easy to sort by date (you can watch your photos by progression in time), before you opened a photo you see when it were made.

So, can I do that, of corse, I can get date from exif and rename it having this date, and I created a script in Bash, but now I rewrote it Python

To use this script you requered to have Python Python and installed pyexiv2 module

Source code:
#! /usr/bin/python

import os
import sys
import argparse
import pyexiv2
import re
import datetime


def getDatetime(filename, itime=False):
    metadata = pyexiv2.ImageMetadata(filename)
    try:
        metadata.read()
        if itime:
            dtime = metadata["Exif.Image.DateTime"]
        else:
            dtime = metadata["Exif.Photo.DateTimeOriginal"]
    except:
        return False
    else:
        return dtime.value


def getFilesData(path, recursive=False, nofilters=False, itime=False):
    filedict = {}
    for filename in os.listdir(path):
        fullpath = os.path.join(path, filename)
        alreadyRenamed = False
        if os.path.isdir(fullpath):
            if recursive:
                filedict = dict(filedict.items() + getFilesData(fullpath, recursive, nofilters, itime).items())
            else:
                continue
        if not nofilters:
            alreadyRenamed = re.match("^[0-9]{4}_[0-9]{2}_[0-9]{2}_[0-9]{2}_[0-9]{2}_[0-9]+\.jpg", filename.lower())
        if filename.lower().endswith(".jpg") and not alreadyRenamed:
            dtime = getDatetime(fullpath, itime)
            if isinstance(dtime, datetime.datetime):
                filedict[fullpath] = dtime
    return filedict


def renameFiles(filedict):
    scount = [0, len(filedict)]
    for item in filedict:
        path, filename = os.path.split(item)
        dtime = filedict[item]
        for a in range(1000):
            newname = "%04d_%02d_%02d_%02d_%02d_%d.jpg" % (dtime.year, dtime.month, dtime.day, dtime.hour, dtime.minute, a)
            if not os.path.exists(os.path.join(path, newname)):
                try:
                    os.rename(item, os.path.join(path, newname))
                except:
                    print "rename Error"
                    pass
                else:
                    scount[0] = scount[0] + 1
                break
    return scount


def printDates(filedict):
    for item in filedict:
        print filedict[item], item


def checkNames(filedict):
    newdict = {}
    for item in filedict:
        path, filename = os.path.split(item)
        dtime = filedict[item]
        regex = "^%04d_%02d_%02d_%02d_%02d_[0-9]+\.jpg" % (dtime.year, dtime.month, dtime.day, dtime.hour, dtime.minute)
        if not re.match(regex, filename):
            newdict[item] = filedict[item]
    return newdict


def main():
    parser = argparse.ArgumentParser(description="Script gets images exiv datastamps, shows it or renames it in proper name")
    parser.add_argument("-r", "--recursive", help="Find files recursively", action="store_true")
    parser.add_argument("-R", "--rename", help="Rename file if needed", action="store_true")
    parser.add_argument("-n", "--nofilters", help="Do not filter files by patern ????_??_??_??_??_*.jpg", action="store_true")
    parser.add_argument("-c", "--check", help="Compare filename and exiv timestamp", action="store_true")
    parser.add_argument("-i", "--imagetimestamp", help="Take image timestamp instead of photo timestamp", action="store_true")
    parser.add_argument("dirname", help="Directory name where to start, by default current", nargs="?", default=".")
    args = parser.parse_args()
    path = os.path.abspath(args.dirname)
    filedict = {}

    filedict = getFilesData(path, args.recursive, args.nofilters, args.imagetimestamp)
    if args.check:
        filedict = checkNames(filedict)
    if args.rename:
        scount = renameFiles(filedict)
        print "%d files renamed out of %d" % (scount[0], scount[1])
    else:
        printDates(filedict)

if __name__ == "__main__":
    main()
Яндекс.Метрика