Automatically organising & optimising photos and videos with Bash
As I promised recently, this post is about a script I implemented a while back that automatically organises and optimises the photos and videos that I take for me. Since I've been using it a while now and it seems stable, I thought I'd share it here in the hopes that it might be useful to someone else too.
I take quite a few photos and the odd video or two with my phone. These are automatically uploaded to a Raspberry Pi 3B+ that's acting as a file server on my home network with FolderSync (yes, it has ads, but it's the best I could find that does the job). Once uploaded to a folder, I then wanted a script that would automatically sort the uploaded images and videos into folders by year and month according to their date taken.
To do this, I implemented a script that uses exiftool
(sudo apt install libimage-exiftool-perl
I believe) to pull out the date taken from JPEGs and sort based on that. For other formats that don't support EXIF data, I take the last modified time with the date
command and use that instead.
Before I do this though, I run my images through a few preprocessing tools:
- PNGs are optimised with
optipng
(sudo apt install optipng
) - JPEGs are optimised with
jpegoptim
(sudo apt install jpegoptim
) - JPEGs are additionally automatically reoriented with
mogrify -auto-orient
from ImageMagick, as many cameras will set an EXIF tag for the rotation of an image without bothering to physically rotate the image itself
It's worth noting here that these preprocessing optimisation steps are lossless. In other words, no quality lost by performing these actions - it simply encodes the images more efficiently such that they use less disk space.
Once all these steps are complete, images and videos are sorted according to their date taken / last modified time as described above. That should end up looking a bit like this:
images
+ 2019
+ 07-July
+ image1.jpeg
+ 2020
+ 05-May
+ image2.png
+ image3.jpeg
+ 06-June
+ video1.mp4
Now that I've explained how it works, I can show you the script itself:
(Can't see the above? Check out the script directly on GitLab here: organise-photos)
The script operates on the current working directory. All images directly in the working directory will be sorted as described above. Once you've put it in a directory that is in your PATH
, simply call it like this:
organise-photos
The script can be divided up into 3 distinct sections:
- The setup and initialisation
- The function that sorts individual files themselves into the right directory (
handle_file
- it's about half-way down) - The preprocessing steps and the driver code that calls the above function.
So far, I've found that it's been working really rather well. During development and testing I did encounter a number of issues with the sorting system in handle_file
that caused it to sort files into the wrong directory - which took me a while finally squash.
I'm always tweaking and improving it though. To that end, I have several plans to improve it.
Firstly, I want to optimise videos too. I'd like to store them in a standard format if possible. It's not that simple though, because some videos don't take well to being transcoded into a different format - indeed they can even take up more space than they did previously! In those cases it's probably worth discarding the attempt at transcoding the video to a more efficient format if it's larger than the original file.
I'd also like to reverse-geocode (see also the usage policy) the (latitude, longitude) geotags in my images to the name of the place that I took them, and append this data to the comment EXIF tag. This will make it easier to search for images based on location, rather than having to remember when I took them.
Finally, I'd also like to experiment with some form of AI object recognition with a similar goal as reverse-geocoding. By detecting the objects in my images and appending them to the comment EXIF tag, I can do things like search for "cat", and return all the images of cats I've taken so far.
I haven't started to look into AI much yet, but initial search results indicate that I might have an interesting time locating an AI that can identify a large number of different objects.
Anyway, my organise-photos
script is available on GitLab in my personal bin folder that I commit to git if you'd like to take a closer look - suggestions and merge requests are welcome if you've got an idea that would make it even better :D