Sorting Images based on Exif data

Suppose you have a folder containing images taken by a digital camera over a period of time, wouldn't it be nice to sort these images into folders?

The script below copies folders from one folder to another, creating subfolders in the target folder with the name of YYYY-MM (2010-07).

Usage:

Save the script in your home folder e.g. imagecopy.php, and adjust the source and target folder names in the script. Then, execute the script

php -f ~/imagecopy.php

The script won't overwrite existing files in $target. But still, be careful with your images. Better try with backups first.

<?php
 
$filetypes = array('jpg','jpeg');
$source = './images_unsorted';
$target = './images_sorted';
 
$iterator = new RecursiveDirectoryIterator($source);
 
$bytestotal = 0;
$nbfiles = 0;
 
foreach (new RecursiveIteratorIterator($iterator) as $filename=>$fileobj) {
 
  $basename = $fileobj->getBasename();
  $extension = strtolower(substr($basename, strrpos($basename, '.')+1));
 
  if (in_array($extension, $filetypes)) {
 
    // read creation date from exif information, otherwise mtime
 
    echo $filename."\n";
    $exif = exif_read_data($filename, 'IFDO', 0);
    if ($exif!==false && isset($exif['DateTime'])) {
      $edate = $exif['DateTime'];
      $ts = strtotime($edate);
    } else {
      $ts = filemtime($filename);
    }
 
    // target folder
    $datestr = date('Y', $ts).'-'.date('m', $ts);
 
    $targetfolder = $target.'/'.$datestr;
    if (!file_exists($targetfolder)) {
      mkdir($targetfolder);
    }
 
    // copy file
    $targetfile = $targetfolder.'/'.$basename;
    if (!file_exists($targetfile)) {
      copy($filename, $targetfile);
    } else {
      echo "$targetfile exists!\n";
    }
 
  }
 
}
 
$bytestotal=number_format($bytestotal);
echo "Total: $nbfiles files, $bytestotal bytes\n";
 
?>