The site seemed too “static”, so I wanted to add a bit of automation to the images that are displayed on the pages so that I could add and replace them more easily. The first step was to write a script to take a set of photos and reduce them in size so that they load quickly. Most photo images are huge (5 MegaBytes is not unusual) so they won’t render fast enough “as is”, and manually reducing each image was becoming tedious. So – Ruby to the rescue:

#!/usr/bin/env ruby
# Photos from phones are usually very large (MegaBytes), so
# use MiniMagick to automate a file size reduction suitable for
# display as an image on a web page.

# References:
# https://github.com/minimagick/minimagick
# https://www.rubyguides.com/2018/12/minimagick-gem/
require "mini_magick"

# The photos to be processed are assumed to be in the current directory
image_list = `ls -1`.split("\n")

# Photos from phones often have spaces (" ") in the name, e.g. "xyz 123.JPG"
# Change spaces to underscores ("_")
# We want to keep the original photo, so use the open method and
# write a new file as "xyz_123_r.JPG" (r for "reduced")
image_list.each do |image|
  renamed_image = image.gsub(" ", "_").upcase
  reduced_image = renamed_image.gsub(".JPG", "_r.JPG")
  puts "Processing #{image}"
  working_image = MiniMagick::Image.open(image)

  # These settings were determined by trial and error, YMMV
  working_image.combine_options do |o|
    o.strip
    o.geometry 960
    o.quality 50
  end

  working_image.write(reduced_image)
end

The MiniMagick gem acts as a front end to ImageMagick. Given a directory of photos to be reduced (line 12), the code selects each photo (line 18) and processes it to create a reduced image (lines 25 – 29). Typically, an image can go from a few MegaBytes in size to less than 200k bytes, often less than 100k. I have noticed that a few photos are a bit grainy, but most of them still look pretty damn good.

The reduced images are moved into a MiddleMan source/images sub-directory called randomized (real original, I know). BTW, the script can be picked up as a GitHub Gist.)

Then add a bit of helper code in the MiddleMan config.rb file to randomly select an image:

helpers do
  def generate_random_image
    `ls -1 source/images/randomized`.split("\n").sample
  end
end

And then in the page views (HAML format), call the helper to randomly select an image:

  - random_image = generate_random_image
  %div.text-center
    %img.img-fluid{"src": "/images/randomized/#{random_image}",
                           "alt": "random_image"}

Now every time I recompile the pages (via bundle exec middleman build), I get a new set of randomly generated images that I can push to production. Sweet!