SoFunction
Updated on 2025-04-10

Batch production photo organizer


:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Author: namejm
:: Source:
:: Date of writing: 2007-10-29~2008-9-3
:: Test environment: CMD@WinXP SP2
:: Function: Classify photos according to exif information
:: Detailed introduction:
:: This script classifies pictures by obtaining exif information of jpg photos, and has two types: resolution and date.
:: method to classify and automatically rename files with the same name, while counting the number of photos that have been processed. In addition, you can choose
:: Choose to use the following functions:
:: 1. Bulkly correct the modification date of jpg photos in the current directory and all subdirectories to be the shooting date;
:: 2. It can move all pictures in the subdirectory to the parent directory and delete all empty directories in the parent directory.
:: Notice:
:: This script will read the exif information of the photo. When organizing the photo by date, it will automatically correct the photo modification time.
:: The time of the photo is taken, the time is accurate to seconds; the jpg picture without exif information remains unchanged.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
mode con lines=30
set TT=Photo Organizer 1.4
color 1f

:source
title %TT% Current directory: "%cd%"
cls
echo ╭─────────╮
echo ╭────────────────────────────────────────�
echo │ ╰─────────╯ │
echo │ │
echo │ This program can use jpg format photos under the specified path according to resolution │
echo │ │
echo │ The size or shooting date is sorted into a folder in the following format: │
echo │ │
echo │ 1 Resolution size (such as 800×600) │
echo │ │
echo │ 2 years - month - day (such as 2007-01-01) │
echo │ │
echo │ March \ Date (such as 01\2007-01-01) │
echo │ │
echo │ 4 years\date (such as 2007\2007-01-01) │
echo │ │
echo │ 5 years\month\date (such as 2007\01\2007-01-01) │
echo │ │
echo │ Note: This script will automatically correct when it classifies photos by date │
echo │ │
echo │ The creation time of the photo is the shooting time in the exif information of the photo, accurate to │
echo │ │
echo │ seconds. For jpg images without exif information, the modification time remains unchanged. │
echo │ │
echo ╰────────────────────────────╯
echo.
echo To process the current directory, please press 0
echo ──────────────────────────────
set Source=
set /p Source= Please drag the folder to be processed to this window:
if not defined Source set "Source=%cd%"
set "Source=%Source:"=%"
if "%Source%"=="0" exit
if not exist "%Source%\" goto source
echo "%Source%"|find ":">nul 2>nul||set "Source=%cd%\%Source%"
title %TT% Processing directory: "%Source:"=%"

:fixtime
cls
echo ╭─────────╮
echo ╭─────────┤Revised the date of modification of the photo├──────────────────────────
echo │ ╰─────────╯ │
echo │ │
echo │ The time of the photo is included in the exif information and reflected in the original │
echo │ │
echo │ In the photo file, it is the time for the photo to be modified. │
echo │ │
echo │ Unfortunately, the time for photo modification is not sometimes exif │
echo │ │
echo │ The shooting time in the information is completely consistent, such as: the photo is edited, counted │
echo │ │
echo │ After restoring, etc., which makes it difficult to view the time of the photo modification │
echo │ │
echo │ To determine the shooting time of the photo, and to make the investment according to the shooting time in some cases │
echo │ │
echo │ In the case of archived materials, such a situation is undoubtedly a disaster. │
echo │ │
echo │ This function can repair photos in designated directories and all subdirectories │
echo │ │
echo │ Change the time to reset the photo shooting time—just the exif of the photo │
echo │ │
echo │ The information is not destroyed. │
echo │ │
echo ╰────────────────────────────╯
echo.
echo Go back to the previous step, press 1, exit, press 0
echo ──────────────────────────────
set FixTime=
set /p FixTime= Whether to correct the modification time of the photo to the shooting time (Y = Y No = any other key):
if not defined FixTime goto movesub
set "FixTime=%FixTime:"=%"
if "%FixTime%"=="0" exit
if "%FixTime%"=="1" goto source
if /i "%FixTime%"=="y" (
jhead -ft "%Source%\*.jpg">nul 2>nul
for /f "delims=" %%i in ('dir /ad /b /s "%Source%" 2^>nul') do (
jhead -ft "%%i\*.jpg">nul 2>nul
title %TT% Processing directory: "%%i"
)
)

:movesub
cls
echo.&echo.&echo.
echo ╭─────────╮
echo ╭────────────────────────────────────────�
echo │ ╰─────────╯ │
echo │ │
echo │ If there are photos in the subdirectory of the current directory, you need to put │
echo │ │
echo │ They are all placed in the parent directory and delete the parent directory and all its subdirectories │
echo │ │
Empty folders of echo │, then this function will be very useful. │
echo │ │
echo │ Note: The empty folder here refers to deleting the parent directory and all its children │
echo │ │
echo │ An empty folder formed after the *.ctg file in the directory, to │
echo │ │
echo │ and empty folders that already exist. │
echo │ │
echo ╰────────────────────────────╯
echo.
echo Go back to the previous step, press 1, exit, press 0
echo ──────────────────────────────
echo.
set MoveSub=
set /p MoveSub= Whether to move the photo to the parent directory and delete the empty directory (Y = Y No = N):
if not defined MoveSub goto movesub
set "MoveSub=%MoveSub:"=%"
if not defined MoveSub goto movesub
if "%MoveSub%"=="0" exit
if "%MoveSub%"=="1" goto source
if /i "%MoveSub%"=="y" (
set num=0
set WhetherMove=M
for /f "delims=" %%i in ('dir /ad /b /s "%Source%\" 2^>nul') do (
for /f "delims=" %%j in ('dir /a-d /b /s "%%i\*.jpg" 2^>nul') do (
set route=&set postfix=
setlocal enabledelayedexpansion
call :re_name "%%j" "%Source%" "%%~nj"
move "%%j" "!Destination_1!">nul 2>nul
endlocal
set /a num+=1
)
title %TT% File is being processed: "%%i"
)
del /a /f /q /s "%Source%\">nul 2>nul
del /a /f /q /s "%Source%\*.ctg">nul 2>nul
for /f "delims=" %%i in ('dir /ad /b /s "%Source%\"^|sort /r') do (
rd /q "%%i" 2>nul&title %TT% Processing file: "%%i"
)
title %TT% Directory being processed: "%Source%"
echo.&call echo A total of %%num%% photos have been processed, press any key to continue...
pause>nul
) else if /i not "%MoveSub%"=="n" goto movesub

:whethermove
cls
echo.
echo ╭─────────╮
echo ╭──────────────────────────────────────────────────────────────────────────
echo │ ╰─────────╯ │
echo │ │
echo │ If you do not want to delete the photos you want to process in the folder, please select │
echo │ │
echo │ Production function; if the original photos are not retained, please select Move the file. │
echo │ │
echo │ Note: After moving the file, all empty texts in the parent directory will be deleted │
echo │ │
echo │ folder. The empty folder here refers to deleting the parent directory and all its subdirectories │
echo │ │
The empty folder formed after the *.ctg file under echo │ and the original │
echo │ │
echo │ The empty folder that already exists. │
echo │ │
echo │ Also: The file with the same name will be renamed, the specific method is: in the text │
echo │ │
echo │ Add after the name of the item - serial number. For example, rename it to │
echo │ │
echo ╰────────────────────────────╯
echo.
echo Go back to the previous step, press 1, exit, press 0
echo ──────────────────────────────
echo.
set WhetherMove=
set /p WhetherMove= Move or copy file (mov = M copy = C):
if not defined WhetherMove goto whethermove
set "WhetherMove=%WhetherMove:"=%"
if "%WhetherMove%"=="0" exit
if "%WhetherMove%"=="1" goto movesub
set flag=
if /i "%WhetherMove%"=="M" set flag=1
if /i "%WhetherMove%"=="C" set flag=1
if not defined flag goto whethermove
if /i "%MoveSub%"=="y" goto destination

:whethersub
echo.
set WhetherSub=
set /p WhetherSub= Whether or not to process subdirectories (Y = Y No = N):
if not defined WhetherSub goto whethersub
set "WhetherSub=%WhetherSub:"=%"
if /i "%WhetherSub%"=="0" exit
if /i "%WhetherSub%"=="1" goto whethermove
if /i "%WhetherSub%"=="y" (
set WhetherSub=/s
goto destination
)
if /i "%WhetherSub%"=="n" (
set WhetherSub=
goto destination
)
goto whethersub

:destination
echo.
title %TT% The directory where the program is located: "%cd%"
set Destination=
set /p Destination= Please enter the save path (save it in the directory where the program is located, please enter it directly):
if not defined Destination set "Destination=%cd%"
set "Destination=%Destination:"=%"
if "%Destination%"=="0" exit
if "%Destination%"=="1" goto whethermove
echo "%Destination%"|find ":">nul 2>nul||set "Destination=%cd%\%Destination%"
echo "%Destination%"|find /i "%Source%">nul 2>nul&&(
cls
for /l %%i in (1,1,7) do echo.
In order not to process photos repeatedly, echo is not allowed to set the save path to the directory where the source file is located.
echo.&echo Please reset the save path
echo.&echo.
goto destination
)
md "%Destination%" 2>nul

:wise
cls
echo.&echo.&echo.&echo.&echo.
echo ╭────────╮
echo ╭────────────────────────────────────────�
echo │ ╰────────╯ │
echo │ │
echo │ There are two ways to organize: │
echo │ │
echo │ a Organize according to file size (such as 800×600) │
echo │ │
echo │ b Organize according to the shooting date (such as 2008-01-01) │
echo │ │
echo ╰────────────────────────────╯
echo.
echo Go back to the previous step, press 1, exit, press 0
echo ──────────────────────────────
echo.
set Wise=
set /p Wise= Please select (a/b):
if not defined Wise goto wise
set "Wise=%Wise:"=%"
if not defined Wise goto wise
if "%Wise%"=="0" exit
if "%Wise%"=="1" goto whethermove
if /i "%Wise%"=="a" goto folders_dimesion
if /i "%Wise%"=="b" goto folders_date
goto wise

:folders_dimesion
cls
for /l %%i in (1,1,10) do echo.
echo is being processed, please wait...
set num=0
call :dimesion "%Source%"
if defined WhetherSub (
for /f "delims=" %%i in ('dir /ad /b /s "%Source%" 2^>nul') do call :dimesion "%%i"
)
call :del_blank
pause>nul&goto source

:folders_date
cls
echo.&echo.&echo.
echo ╭─────────╮
echo ╭────────────────────────────────────────�
echo │ ╰─────────╯ │
echo │ │
echo │ Under the save path, a text named after the date of the photo will be created │
echo │ │
echo │ folders, the directory tree structure of these folders is as follows: │
echo │ │
echo │ a year - month - day (such as 2007-01-01) │
echo │ │
echo │ b month\date (such as 01\2007-01-01) │
echo │ │
echo │ c Year\Date (such as 2007\2007-01-01) │
echo │ │
echo │ d year\month\date (such as 2007\01\2007-01-01) │
echo │ │
echo ╰────────────────────────────╯
echo.
echo Go back to the previous step, press 1, exit, press 0
echo ──────────────────────────────
echo.
set FoldersTree=
set /p FoldersTree= Please select (a/b/c/d):
if not defined FoldersTree goto folders_date
set "FoldersTree=%FoldersTree:"=%"
if "%FoldersTree%"=="0" exit
if "%FoldersTree%"=="1" goto whethermove
set choice=
for %%i in (a b c) do if /i "%FoldersTree%"=="%%i" set choice=1
if not defined choice goto folders_date
cls
for /l %%i in (1,1,10) do echo.
echo is being processed, please wait...
set num=0
for /f "delims=" %%i in ('dir /a-d /b %WhetherSub% "%Source%\*.jpg" 2^>nul') do (
set /a num+=1
jhead -ft "%%i">nul 2>nul
if defined WhetherSub (
for /f "delims=" %%j in ("%%i") do (
set str=%%~tj
set route=&set postfix=
setlocal enabledelayedexpansion
set str=!str:~0,10!
set Y=!str:~0,4!&set M=!str:~5,2!&set D=!str:~8,2!
if /i "%FoldersTree%"=="a" set Y=&set M=
if /i "%FoldersTree%"=="b" set Y=
if /i "%FoldersTree%"=="c" set M=
md "%Destination%\!Y!\!M!\!str!" 2>nul
if /i "%WhetherMove%"=="M" (
call :re_name "%Source%\%%i" "%Destination%\!Y!\!M!\!str!" "%%~ni"
move "%%j" "!Destination_1!">nul 2>nul
) else (
call :re_name "%Source%\%%i" "%Destination%\!Y!\!M!\!str!" "%%~ni"
copy "%%j" "!Destination_1!">nul 2>nul
)
title %TT% File is being processed: "%%i"
endlocal
)
) else (
for /f "delims=" %%j in ("%Source%\%%i") do (
set str=%%~tj
set route=&set postfix=
setlocal enabledelayedexpansion
set str=!str:~0,10!
set Y=!str:~0,4!&set M=!str:~5,2!&set D=!str:~8,2!
if /i "%FoldersTree%"=="a" set Y=&set M=
if /i "%FoldersTree%"=="b" set Y=
if /i "%FoldersTree%"=="c" set M=
md "%Destination%\!Y!\!M!\!str!" 2>nul
if /i "%WhetherMove%"=="M" (
call :re_name "%Source%\%%i" "%Destination%\!Y!\!M!\!str!" "%%~ni"
move "%%j" "!Destination_1!">nul 2>nul
) else (
call :re_name "%Source%\%%i" "%Destination%\!Y!\!M!\!str!" "%%~ni"
copy "%%j" "!Destination_1!">nul 2>nul
)
title %TT% Processing file: "%Source%\%%~nxi"
endlocal
)
)
)
call :del_blank
pause>nul&goto source

:dimesion
:: Create a folder under the destination path according to the pixel value
for /f "tokens=2,3*" %%i in ('jhead -cs nul "%~1\*.jpg" 2^>nul^|findstr /i "name Resolution" 2^>nul') do (
if "%%j"==":" (
set "Source=%%k"&set "name=%%~nk"
title %TT% File is being processed: "%%k"
) else (
setlocal enabledelayedexpansion
set "dimesion=%%j%%k"
set "dimesion=!dimesion:x =×!"
set "Destination=%Destination%\!dimesion!"
md "!Destination!" 2>nul
set route=&set postfix=
if /i "%WhetherMove%"=="M" (
call :re_name "!Source!" "!Destination!" "!name!"
move "!Source!" "!Destination_1!">nul 2>nul
) else (
call :re_name "!Source!" "!Destination!" "!name!"
copy "!Source!" "!Destination_1!">nul 2>nul
)
endlocal
set /a num+=1
)
)
goto :eof

:re_name
if not defined route (
set "route=%~2"
set "filename=%~3"
)
:re_name_loop
if not exist "%route%\%filename%%postfix%.jpg" (
set "Destination_1=%route%\%filename%%postfix%.jpg"
set _num=0
goto :eof
) else (
set /a _num+=1
call set "postfix=-%%_num%%"
goto re_name_loop
)
goto :eof

:del_blank
if /i "%WhetherMove%"=="M" (
del /a /f /q /s "%Source%\">nul 2>nul
del /a /f /q /s "%Source%\*.ctg">nul 2>nul
for /f "delims=" %%i in ('dir /ad /b /s "%Source%\"^|sort /r') do (rd /q "%%i" 2>nul)
rd /q "%Source%" 2>nul
)
title %TT% Current directory: "%cd%"
echo.&echo.&echo A total of %num% photos have been processed, press any key to continue...
goto :eof