Manage photos with BAT files.

I have about 5000 photos in my archive. About two days ago they were on two computers, in different folders, some of them had wrong names or creation date and some photos are copied multiple times. They occupied a lot of space and it was hard to backup all of them.

So, I decided to change the situation and create a few simple rules that make my photo collection better organized and apply them for existing photos. And these rules should not be complex (I'm very skeptical in my ability to label each photo with tags) and allows me to quickly navigate over the collection and find photos. And here they are:

  • Pictures are stored in folders, one day - one folder. Folders are named as follows: year_month_day - label1, label2, label3, ...
  • Pictures are named as follows: img-year-month-day-hour-minute-second.jpg.
  • Movies are named as follows: mvi-year-month-day-hour-minute-second.jpg.
  • Each movie should have related THM file (160x120 JPG file with EXIF information about the movie).
  • Date of the file should match the date saved in EXIF info.

The first step was very simple, I hust copied all the folders with photos into one folder.

Then I found all AVI files with missed THM file. For this I executed the following command from the command prompt:

@for /r %i in (*.avi) do @if not exist "%~dpni.thm" @echo %i

This commands searches for all files with the avi extension in current folder and its subfolders and prints the name of the AVI file when corresponding thm file does not exist.

Fortunately, only three files lost their thm files and I've created them manually.

To create the thm file, just open the movie and create screenshot of the first frame, resize it to 160x120, save as jpg file and change the extension to thm. The AVI and THM should have the same name, so if the name of the avi file is MVI_12345.avi, the name of the THM file should be MVI_12345.thm. Then with the help of the jhead program, adjust the date/time EXIF header in the thm files.

I assumed that files with the same EXIF date/time are the same files, because my camera cannot take more then one picture per second. So, I replaced file creation dates to what is stored in EXIF header and renamed the files with the following bat file:

@echo off

rem THIS SOFTWARE IS PROVIDED BY Alex Netkachov (http://www.alexatnet.com)
rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
rem FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
rem COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
rem INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
rem BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
rem LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
rem CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
rem LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
rem ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
rem POSSIBILITY OF SUCH DAMAGE.

rem This script:
rem   1. Set file creation dates to what is stored in EXIF header
rem   2. Rename jpg images to img-yyyy-mm-dd-hh-nn-ss.jpg
rem   3. Rename avi images to mvi-yyyy-mm-dd-hh-nn-ss.avi
rem   4. Rename thm video thumbnails to mvi-yyyy-mm-dd-hh-nn-ss.thm
rem   5. Set readonly attribute for all processed files
rem   6. Prints list of duplicated files.

rem This script uses jhead.exe (http://www.sentex.net/~mwandel/jhead/).

setlocal disabledelayedexpansion
for /r %%i in (*.jpg *.thm) do call :process_file "%%i"
endlocal
goto :eof

:process_file
    jhead.exe -ft %1 > nul
    jhead.exe %1 | findstr /c:"File date" > fileinfo.txt
    set /p file_datetime=< fileinfo.txt
    del fileinfo.txt
    call :fd "%file_datetime%" %1
    goto :eof

:fd
    set dt=%1
    set dyear=%dt:~16,4%
    set dmonth=%dt:~21,2%
    set dday=%dt:~24,2%
    set dhour=%dt:~27,2%
    set dminutes=%dt:~30,2%
    set dseconds=%dt:~33,2%
    set fdt=%dyear%-%dmonth%-%dday%-%dhour%-%dminutes%-%dseconds%
    if not exist %dyear%_%dmonth%_%dday% mkdir %dyear%_%dmonth%_%dday%
    if /i "%~x2" == ".jpg" goto extjpg
    if /i "%~x2" == ".thm" goto extthm
    goto :eof
    :extjpg
        if exist %dyear%_%dmonth%_%dday%\img-%fdt%.jpg (
            echo "%~2" is a possible duplicate of %dyear%_%dmonth%_%dday%\img-%fdt%.jpg.
        ) else (
            move "%~2" %dyear%_%dmonth%_%dday%\img-%fdt%.jpg
            attrib +r %dyear%_%dmonth%_%dday%\img-%fdt%.jpg
        )
    goto :eof
    :extthm
        if exist %dyear%_%dmonth%_%dday%\mvi-%fdt%.thm (
            echo "%~2" is a possible duplicate of %dyear%_%dmonth%_%dday%\mvi-%fdt%.thm.
        ) else (
            move "%~2" %dyear%_%dmonth%_%dday%\mvi-%fdt%.thm
            attrib +r %dyear%_%dmonth%_%dday%\mvi-%fdt%.thm
        )
        if exist %dyear%_%dmonth%_%dday%\mvi-%fdt%.avi (
            echo "%~2" is a possible duplicate of %dyear%_%dmonth%_%dday%\mvi-%fdt%.avi.
        ) else (
            move "%~dpn2.avi" %dyear%_%dmonth%_%dday%\mvi-%fdt%.avi
            attrib +r %dyear%_%dmonth%_%dday%\mvi-%fdt%.avi
        )
    goto :eof

This script does not remove duplicated files. Instead it shows the list of duplicates and keeps them in the main folder so you can decide which of them should be deleted.

And if you like to try this script, remember: BACKUP YOUR DATA FIRST!