Optimizing JPG and PNG Images for a Jekyll Website

Optimizing JPG and PNG Images for a Jekyll Website

This website has been text oriented for a long time now. The decision to add article banners and thumbnails is a recent decision. I stayed away from images for a long time as handling and optimizing images can be a PITA. I was happy to find that optipng, jpegoptim, and imagemagick already exists to solve this problem for me.

My plan is as follows:

I already have all the article pictures in my static/images folder. From there, I will generate two copies of all PNG and JPG images. The first would be a cropped thumbnail version measuring 422 x 316. The second would be a larger banner version measuring 1024×768.

Both copies, thumbnail and banner will be in their own folders. I will then utilize Jekyll’s custom variables for the folder paths.

Installing The Binaries

On my Mac OS X, installing binaries required a single brew command.

brew install optipng jpegoptim imagemagick

Creating folders for thumbnails and banners

Next, I will create new folders below static/images. Thumbnails will go in img-thumbs and banners will enter img-normal.

cd static/images
mkdir -p img-thumbs img-normal

With the folders created, I copy all of them first GIF, SVG, JPG, and PNG files for both folders. I will use GIFs and SVGs as they are for thumbnails and banner images.

cp content/*.gif img-thumbs/; cp content/*.gif img-normal/
cp content/*.svg img-thumbs/; cp content/*.svg img-normal/
cp content/*.jpg img-thumbs/; cp content/*.jpg img-normal/
cp content/*.png img-thumbs/; cp content/*.png img-normal/

Processes thumbnails

Let’s first resize and optimize the thumbnails. As previously mentioned, I want the thumbnails to be 422 x 316. I want to use mogrify command from ImageMagick to resize JPGs and PNGs.

cd img-thumbs
mogrify -resize 422x316 *.png
mogrify -format jpg -resize 422x316 *.jpg

Let us now optimize PNGs using optipng and JPGs using jpegoptim.

for i in *.png; do optipng -o5 -quiet "$i"; done
jpegoptim -sq *.jpg

In the above command:

  1. To optipng, -o5 swtich sets the optimization level, where zero is the lowest.
  2. To jpegoptim, -s removes all image metadata, and -q sets the silent mode.

Processing of banners

I process the banner images as I processed the thumbnails above. Except for the file dimensions, everything else will remain the same.

cd ..
cd img-normal
mogrify -resize 1024x768 *.png
mogrify -format jpg -resize 1024x768 *.jpg
for i in *.png; do optipng -o5 -quiet "$i"; done
jpegoptim -sq *.jpg

Configuration of the trails in Jekyll

img-thumbs now contains my thumbnails and img-normal contains the banners. To make my life easier, I will set them both to Jekyll variables in _config.yml.

content-images-path: /static/images/img-normal/
content-thumbs-images-path: /static/images/img-thumbs/

It’s easy to use these. When I want to show the thumbnail, I put it in front content-thumbs-images-path to the image. When I want to show the whole banner, I sit in front content-images-path.

For example, articles on this site now have one banner_img property in front case. The value of this property is the name of the image file. To display the thumbnail for the article, I use the following code:

{% if page.banner_img %}
 <img src="https://dzone.com/articles/{{ page.banner_img" prepend: site.content-images-path | prepend: site.baseurl | prepend: site.url }}" alt="Banner image for {{ page.title }}" />
{% endif %}


There are several improvements we can make to the commands above. The most obvious may be to use rsync only copy modified files to img-thumbs and img-normal. That way, we do not reprocess files over and over again. Another improvement might be to add these commands to Git pre-commit hooks or a CI pipeline.

Resizing and optimizing images to reduce their size is a benefit for the user and the Internet as a whole. Fewer bytes transmitted over the line means a lower CO2 footprint, but that’s another article. The UX victory is good enough for now 🙂

Have fun coding 🙂


Please enter your comment!
Please enter your name here