public
Last active

Do you own a DSLR? If so, do you transfer your images to your computer, then look at the JPEGs and delete the crappy ones? If you do, your RAW images may be leftover. This Python script helps you cleaning up your image folders after deleting unwanted JPEGs. See http://blog.philippklaus.de/2012/12/cleaning-leftover-raw-images-after-selecting-images-based-on-jpegs/ for more information.

  • Download Gist
remove-orphaned-raw-images.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
 
"""
Written on 2012-12-12 by Philipp Klaus <philipp.l.klaus →AT→ web.de>.
Check <https://gist.github.com/4271012> for newer versions.
 
Also check <https://gist.github.com/3155743> for a tool to
rename JPEGs according to their EXIF shot time.
"""
 
import argparse, os, errno, re, shutil, sys
 
def stderr(line):
sys.stderr.write(line + '\n')
sys.stderr.flush()
 
def delete(files, backup_folder=None, verbose=True):
if len(files) == 0: return
if backup_folder:
try:
os.mkdir(backup_folder)
except OSError, e:
if not e.errno == errno.EEXIST:
raise
for filename in files:
if verbose: print "Moving %s to %s." % (filename, backup_folder)
shutil.move(filename, os.path.join(backup_folder))
else:
for filename in files:
if verbose: print "Deleting %s." % (filename,)
os.remove(filename)
 
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Cleanup of leftover raw image files (*.CR2).')
parser.add_argument('-n', '--no-backup', action='store_true',
help='Don\'t backup orphaned raw images - delete them immediately.')
parser.add_argument('-b', '--backup-folder', default='raw_orphans',
help='Folder to move orphaned raw images to.')
parser.add_argument('-q', '--quiet', action='store_true',
help='Silence the less important output of this tool.')
parser.add_argument('folder', metavar='CHECK_FOLDER', default='./', nargs='?',
help='Folder to check for raw images. Defaults to the current working directory')
args = parser.parse_args()
verbose = not args.quiet
raw_images, jpeg_images_bare_names = [], []
all_files = list(os.listdir(args.folder))
# sort files into raw and jpeg files
for filename in all_files:
# The file name of raw image ends with .CR2 for Canon EOS cameras
if re.match(r'(.*)\.[cC][rR]2$', filename):
raw_images.append(filename)
if re.match(r'(.*)\.[jJ][pP][eE]?[gG]$', filename):
jpeg_images_bare_names.append(os.path.splitext(filename)[0])
# Check if there is a jpeg for each raw image
orphans = []
for raw_image in raw_images:
if os.path.splitext(raw_image)[0] not in jpeg_images_bare_names:
orphans.append(raw_image)
if len(raw_images) + len(jpeg_images_bare_names) == 0:
if verbose: stderr("No images found. Are you sure you wanted to check '%s' for orphaned RAW images?" %
(args.folder,))
sys.exit(2)
elif len(raw_images) == 0:
if verbose: print "No RAW images found, but %i JPEGs. Won't do anything now." % (
len(jpeg_images_bare_names),)
sys.exit(0)
elif len(orphans) == 0:
if verbose: print "%i RAW images found, and %i JPEGs but no orphans. Won't do anything now." % (
len(raw_images), len(jpeg_images_bare_names))
sys.exit(0)
backup_folder = None if args.no_backup else os.path.join(args.folder,args.backup_folder)
delete([os.path.join(args.folder,orphan) for orphan in orphans], backup_folder=backup_folder, verbose=verbose)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.