Last active
May 9, 2023 14:44
-
-
Save dmuth/0e9738ec6f6811649ea83c5be09f407d to your computer and use it in GitHub Desktop.
Shell script to recursively convert JPG and PNG files to HEIC format.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# This script will convert JPG and PNG files to HEIC format recursively. | |
# | |
# Errors are fatal | |
set -e | |
GO="" | |
DELETE="" | |
JPG="" | |
function print_syntax() { | |
echo "! " | |
echo "! Syntax: $0 ( --go | -jpg ) [ --delete ] " | |
echo "! " | |
echo "! Recursively convert jpeg files to HEIC format or back to jpeg format." | |
echo "! " | |
echo "! --go - Do the conversion, otherwise this script will run in dry mode." | |
echo "! --jpg - Do the reverse and convert HEIC to JPEG. This should be used for uploading to Flickr/Facebook/etc." | |
echo "! --delete - Delete files that have been converted" | |
echo "! " | |
echo "! " | |
exit 1 | |
} # End of print_syntax() | |
if test "$1" == "-h" -o "$1" == "--help" | |
then | |
print_syntax | |
fi | |
while test "$1" | |
do | |
if test "$1" == "--go" | |
then | |
GO=1 | |
elif test "$1" == "--delete" | |
then | |
DELETE=1 | |
elif test "$1" == "--jpg" -o "$1" == "--jpeg" | |
then | |
JPG=1 | |
else | |
print_syntax | |
fi | |
shift | |
done | |
IFS=$'\n' | |
function convert_to_heic() { | |
# | |
# Deternine how many files need to be converted | |
# | |
NUM=0 | |
NUM_CHECKED=0 | |
I=1 | |
echo "# Calculating number of files to convert (This may take a minute...)" | |
for FILE in $(find . -type f \( -iname \*.jpg -o -iname \*.jpeg -o -iname \*.png \)) | |
do | |
TARGET=$(echo ${FILE} | sed -r 's/.[^.]+$/.heic/') | |
NUM_CHECKED=$(( NUM_CHECKED + 1 )) | |
if test $(( NUM_CHECKED % 100)) == 0 | |
then | |
echo -n "${NUM_CHECKED} files checked.. " | |
fi | |
if test ! -s "${TARGET}" | |
then | |
NUM=$(( NUM + 1 )) | |
if test $(( NUM % 100)) == 0 | |
then | |
echo -n "${NUM} files need converting.. " | |
fi | |
fi | |
done | |
echo | |
if test "${NUM}" == 0 | |
then | |
if test "${DELETE}" | |
then | |
echo "# No files left to convert, but we're deleting files, so keep going..." | |
else | |
echo "# No files left to convert and we're not deleting anything, bailing out!" | |
return | |
fi | |
fi | |
for FILE in $(find . -type f \( -iname \*.jpg -o -iname \*.jpeg -o -iname \*.png \)) | |
do | |
TARGET=$(echo ${FILE} | sed -r 's/.[^.]+$/.heic/') | |
if test "${GO}" | |
then | |
if test -s "${TARGET}" | |
then | |
echo "# Ooops--target file '${TARGET}' already exists, skipping!" | |
else | |
echo "# Converting file [${I}/${NUM}] '${FILE}' to '${TARGET}'..." | |
convert "${FILE}" -format heic "${TARGET}" | |
I=$(( I + 1 )) | |
fi | |
if test "${DELETE}" | |
then | |
echo "# Deleting source file ${FILE}..." | |
if test -s "${FILE}" | |
then | |
rm -fv "${FILE}" | |
else | |
echo "! Source file '${FILE}' is not a regular file, skipping deletion!" | |
fi | |
fi | |
else | |
if test -s "${TARGET}" | |
then | |
echo "# Ooops--target file '${TARGET}' already exists, skipping!" | |
else | |
echo "# Dry-Run -- not converting file [${I}/${NUM}] '${FILE}' to '${TARGET}'..." | |
I=$(( I + 1 )) | |
fi | |
fi | |
done | |
} # End of convert_to_heic() | |
# | |
# Convert HEIC back to JPEG. | |
# This is a slimmed down version of convert_to_heic()--it doesn't support deleting files, | |
# for example, as we normally want all roads to lead to HEIC. | |
# | |
function convert_to_jpg() { | |
# | |
# Deternine how many files need to be converted | |
# | |
NUM=0 | |
NUM_CHECKED=0 | |
I=1 | |
echo "# Calculating number of files to convert..." | |
for FILE in $(find . -type f \( -iname \*.heic \) ) | |
do | |
TARGET=$(echo ${FILE} | sed -r 's/.[^.]+$/.jpg/') | |
NUM_CHECKED=$(( NUM_CHECKED + 1 )) | |
if test $(( NUM_CHECKED % 100)) == 0 | |
then | |
echo -n "${NUM_CHECKED} files checked.. " | |
fi | |
if test ! -s "${TARGET}" | |
then | |
NUM=$(( NUM + 1 )) | |
if test $(( NUM % 100)) == 0 | |
then | |
echo -n "${NUM} files need converting.. " | |
fi | |
fi | |
done | |
echo | |
if test "${NUM}" == 0 | |
then | |
if test "${DELETE}" | |
then | |
echo "# No files left to convert, but we're deleting files, so keep going..." | |
else | |
echo "# No files left to convert and we're not deleting anything, bailing out!" | |
return | |
fi | |
fi | |
for FILE in $(find . -type f \( -iname \*.heic \) ) | |
do | |
TARGET=$(echo ${FILE} | sed -r 's/.[^.]+$/.jpg/') | |
if test -s "${TARGET}" | |
then | |
echo "# Ooops--target file '${TARGET}' already exists, skipping!" | |
else | |
echo "# Converting file [${I}/${NUM}] '${FILE}' to '${TARGET}'..." | |
convert "${FILE}" -format jpg "${TARGET}" | |
I=$(( I + 1 )) | |
fi | |
if test "${DELETE}" | |
then | |
echo "# Deleting source file ${FILE}..." | |
if test -s "${FILE}" | |
then | |
rm -fv "${FILE}" | |
else | |
echo "! Source file '${FILE}' is not a regular file, skipping deletion!" | |
fi | |
fi | |
done | |
} # End of convert_to_jpg() | |
if test ! "${JPG}" | |
then | |
convert_to_heic | |
else | |
convert_to_jpg | |
fi | |
echo "# Done!" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment