Giacomo Balli profile picture
Giacomo Balli
Your Technology Advisor

Over two decades of experience at your service.
I help small business owners make better decisions.

Let's Chat LinkedIn

Do you really need a 12MP photo of a goat?

Last month my wife an I went for a weekend getaway to Napa. Great destination: plenty of outdoors activities and a short drive from San Francisco.

We had a great time but when I got back home and transferred all my pictures documenting the trip I noticed they were taking up a ton of disk space. I'm certainly not a photographer but I do enjoy snapping pics mostly for keepsake.

Huge image of a goat shot on iPhone SE.

The original image was 3024 × 4032 (3.1MB) HEIC, this is converted to JPG and downsampled.

One picture in particular caught my attention: a goat. 12MegaPixels almost 10MB... so much quality my naked eye doesn't even know it's there. This got me thinking. I'd like to keep it as part of my memories of things we did during the day but not at that (disk) expense. You can imagine how quickly it will fill-up over time. I need to batch resize all of these.

I also enjoy keeping everything tidy and in-place. Not only did I need to batch resize all images, I also wanted to preserve all image metadata and EXIF data (date, time, location, etc).

I was unable to find a tool to perform such a basic but crucial task so I set out to build it myself. After selecting the best tools and trimming down to the easiest and most efficient code, I came up with the following. I added comments to make it easy to read for anyone. It supports both JPG and HEIC images.

#!/bin/bash

#set max width in pixels
maxwidth=2000

#where are the photos?
if [ $# -eq 0 ]; then
	imgFolder="untitled folder"
else
	imgFolder=$1
fi

cd "$imgFolder"
pwd

#create a temp folder to hold the resampled images
if [ -d new ]; then 
	rm -rf new
fi
mkdir new

#find all JPG images in the specified folder
fileCnt=$(ls *.[jJ][pP]*[Gg] | wc -l)
cnt=0
echo "Will search for JPGs"
find . -maxdepth 1 -iname '*.jp*g' |
while read file
do 
	((cnt++))
	imgwidth=`sips --getProperty pixelWidth "$file" | awk '/pixelWidth/ {print $2}'`
	if [ $imgwidth -gt $maxwidth ]; then
		imgheight=`sips --getProperty pixelHeight "$file" | awk '/pixelHeight/ {print $2}'`
		#skip panorama photos
		if [ $((imgwidth / imgheight)) -lt 2 ]; then
			echo "$cnt/$fileCnt $file $imgwidth → $maxwidth"
			sips -Z $maxwidth "$file" --out new/"$file" > /dev/null 2>&1
			touch -r "$file" new/"$file"
		fi
	fi
done

#find all HEIC images in the specified folder
fileCnt=$(ls *.HEIC | wc -l)
cnt=0
echo "Will search for HEICs"
find . -maxdepth 1 -iname '*.heic' |
while read file
do 
	((cnt++))
	imgwidth=`sips --getProperty pixelWidth "$file" | awk '/pixelWidth/ {print $2}'`
	if [ $imgwidth -gt $maxwidth ]; then
		imgheight=`sips --getProperty pixelHeight "$file" | awk '/pixelHeight/ {print $2}'`
		if [ $((imgwidth / imgheight)) -lt 2 ]; then
			echo "$cnt/$fileCnt $file $imgwidth → $maxwidth"
			sips -s format jpeg -Z $maxwidth "$file" --out new/"$file".jpg  > /dev/null 2>&1
			touch -r "$file" new/"$file".jpg
			rm "$file"
		fi
	fi
done

echo ""
echo "Will replace originals..."
echo "Done!"

rsync -a new/ .
rm -rf new

Save the script as resizeImages.sh, adjust your desired maximum width in pixels, then execute from Terminal like so: ./resizeImages.sh photos (assuming photos is the name of the folder where you dumped all your iPhone images).

To dump all your iPhone images in a folder, I'd recommend Image Capture.

#sips, #imagResize, #batchResize, #macImageResize
Published: Sat, Apr 10 2021 @ 18:58:10
Back to Blog