Pre-generate thumbnails using convert of imagemagick in a Linux or Mac terminal
En Español  

Topics

What we want

Previously I wrote some articles about how to handle the thumbnails in PHP:

https://en.jveweb.net/archives/2010/09/how-to-create-scaled-thumbnails-in-php.html https://en.jveweb.net/archives/2010/09/how-to-create-cropped-and-scaled-thumbnails-in-php.html

This articles talks about the creation of thumbnails on the fly, somebody requests it, it is then created, served, and removed.

How to do it better

While this does the job that is required, it is not the most efficient way to do this. Every time a page is served, the thumbnails are created.

I can think of three ways of make this more efficient, thus resulting in a faster loading speed:

  • We can serve the full-size image, and have Javascript or the browser handle the thumbnails on the visitors machine. The obvious advantage is that our server works less. But we are still serving the full size images. I don’t see this as an elegant way to do it, but with the power now of the browsers, hardly you need to put much thought into this..
  • We can pre-generate the different versions of the image and serve what is best. This will save bandwith and work on the server. This is what we will be doing on this article.
  • We can pre-generate an image containing all of the images to be served, and then use pain CSS to show every part of the image as necessary.

This article will cover the third way. We will use commands to pre-generate the thumbnails needed so we save processor power and loading time and bandwidth, it will cost us some more space in the server. As an example I will use this three images, one 300x300, one 500x300 and one 300x500.

Tools needed

If you have the images in Linux or in a Mac, you just need to have imagemagick installed, a way to check for it is:

convert -version

If you are missing the command, in an Ubuntu/Ubuntu-based distribution you can simply use:

sudo apt install imagemagick

In Mac you can use brew to install imagemagick:

brew install imagemagick

Once imagemagick is available, we can proceed to pre-generate thumbnails.

Scale images by a percentage

This will scale the images to a certain percentage of its size. If it is to 20%, a size of 300 becomes 60, 500 becomes 100. So from images 300x300, 500x300 and 300x500; we get 60x60, 100x60 and 60x100.

for original in *.jpg;
    do
        convert $original \
            -depth 16 \
            -gamma 0.454545 \
            -filter lanczos \
            -scale 20% \
            -gamma 2.2 \
            -quality 100 \
            -sampling-factor 1x1 \
        thumb_20_`echo $original | tr '[:upper:]' '[:lower:]'`;
    done

Reduce the images to no more than X size

This will create a thumbnail with size no side bigger than 100px. In order to keep the proportions so the thumbnails don’t look distorted, in wider images the height will be less than 100 pixels. In taller images the width of less than 100px.

for original in *.jpg; 
    do convert $original \
        -depth 16 \
        -gamma 0.454545 \
        -filter lanczos \
        -resize 100x100 \
        -gamma 2.2 \
        -quality 100 \
        -sampling-factor 1x1 \
        thumb_100x100_`echo $original | tr '[:upper:]' '[:lower:]'`; 
    done

Put all image inside of a box

This one will create a square of 100x100 pixels and it will place the image right in the center. It is like the previous command, only it will extent the shorter side and center the result on the square.

for original in *.jpg; 
    do convert $original \
        -depth 16 \
        -gamma 0.454545 \
        -filter lanczos \
        -resize 100x100 \
        -gamma 2.2 \
        -quality 100 \
        -sampling-factor 1x1 \
        -gravity center \
        -extent 100x100
        thumb_boxed_`echo $original | tr '[:upper:]' '[:lower:]'`; 
    done

Give all images a maximum width

This will create a thumbnail with a width of 100 pixel regardless of the size. In order to keep the proportions so the thumbnails don’t look distorted, some images may be taller and some may be shorter, but all the resulting images will be 100 px wide.

for original in *.jpg; 
    do convert $original \
        -depth 16 \
        -gamma 0.454545 \
        -filter lanczos \
        -resize 100x \
        -gamma 2.2 \
        -quality 100 \
        -sampling-factor 1x1 \
        thumb_w100_`echo $original | tr '[:upper:]' '[:lower:]'`; 
    done

Give all images a maximum height

On the other hand, this will make a thumbnail with a height of 100 px. In order to keep the proportions so the image does not look distorted, some images may be wider while other may be narrower. But all the resulting images will have a height of 100 px.

for original in *.jpg; 
    do convert $original \
        -depth 16 \
        -gamma 0.454545 \
        -filter lanczos \
        -resize 100x \
        -gamma 2.2 \
        -quality 100 \
        -sampling-factor 1x1 \
        thumb_h100_`echo $original | tr '[:upper:]' '[:lower:]'`; 
    done

One-liners

Scale images by a percentage. This will scale the images to a certain percentage of its size.

for original in *.jpg; do convert $original -depth 16 -gamma 0.454545 -filter lanczos -scale 19.3% -gamma 2.2 -quality 100 -sampling-factor 1x1 thumb_20_`echo $original | tr '[:upper:]' '[:lower:]'`; done

Reduce the images to no more than X size. This will create a thumbnail with size no side bigger than 100px.

for original in *.jpg; do convert $original -depth 16 -gamma 0.454545 -filter lanczos -resize 100x100 -gamma 2.2 -quality 100 -sampling-factor 1x1 thumb_100_`echo $original | tr '[:upper:]' '[:lower:]'`; done

Put all image inside of a box. This one will create a square of 100x100 and it will place the image right in the center. It is like the previous command, only it will extent the shorter side and center the result on the square.

for original in *.jpg; do convert $original -depth 16 -gamma 0.454545 -filter lanczos -resize 100x100 -gamma 2.2 -quality 100 -sampling-factor 1x1 -gravity center -extent 100x100 thumb_boxed`echo $original | tr '[:upper:]' '[:lower:]'`; done

Give all images a maximum width. This will create a thumbnail with a width of 100 pixel regardless of the size. Some images may be taller and some may be shorter, but all the resulting images will be 100 px wide.

for original in *.jpg; do convert $original -depth 16 -gamma 0.454545 -filter lanczos -resize 100x -gamma 2.2 -quality 100 -sampling-factor 1x1 thumb_w100_`echo $original | tr '[:upper:]' '[:lower:]'`; done

Give all images a maximum height. This will make a thumbnail with a height of 100 px. Some images may be wider while other may be narrower. But all the resulting images will have a height of 100 px.

for original in *.jpg; do convert $original -depth 16 -gamma 0.454545 -filter lanczos -resize 100x -gamma 2.2 -quality 100 -sampling-factor 1x1 thumb_h100_`echo $original | tr '[:upper:]' '[:lower:]'`; done

Footnotes

For a full reference of the convert command you can look at the reference:

https://legacy.imagemagick.org/Usage/resize/ (I like the legacy better)

https://imagemagick.org/script/convert.php