Creating dev.to-compatible cover images with ImageMagick

5 minute read

The dev.to site recommends that cover images have a particular size. Usually, any image one creates as a cover image doesn’t have this size. ImageMagick to the rescue!

Image file icon with arrow pointing to the right at a dev.to icon
representing converting images to dev.to size recommendation.
Converting images to dev.to cover-image size.
Image credits: BigPicture 3.8 for MacOS 8.61, dev.to

I usually repost articles from my blog to the developer community platform dev.to. This way I can reach a larger audience and hopefully my articles will help more people. On dev.to, cover images have a recommended best size, so I try to match my cover images to their recommendation.

Blog posts (irrespective of where they appear online) that display cover images tend to be more eye-catching than ones without. Thus, I try to create an appropriate image based on the post’s topic. My strategy is to fire up Inkscape and combine some freely-available images (with attribution) in a way which tries to convey in an image what the post is about. Whether or not I succeed is another question! Anyway, the images I create never have the same size as what dev.to recommends.

I used to rescale and pad my cover images by hand in Inkscape to the recommended best size on dev.to. This way I only needed one cover image for each site a post was published on. However, it ended up being a hassle trying to work out what the correct parameters should be so that the exported image resolution came out at approximately 1000x420 and thus fit the dev.to recommendation. As with many things I do, I thought “Surely I can automate this!” and yes, I could. Enter ImageMagick.

With ImageMagick one can script such image manipulations and save time and hassle, especially when running repetitive tasks. I adapted the command line invocation I use from an answer to the StackOverflow question How do I resize and pad an image to a given size using imagemagick?.

The original suggested solution is:

$ convert [input file] -resize 1920x1080 -background black -gravity center -extent 1920x1080 [output file]

where the original poster wanted the padding to be black, hence the -background black option. In my case, filling with white is better, hence I don’t use that and thus the -background option isn’t necessary in the case described here.

My variant (wrapped over multiple lines for better readability) is:

$ convert <input-image-filename>.png \
    -resize 1000x420 -gravity center -extent 1000x420 \
    <output-image_filename>.png

Details, details

Let’s pick this apart a bit to better understand what’s going on.

First up, we’re using the convert command from the ImageMagick toolkit. We use this because we want to convert the input image into the output image using the given options. Note that ImageMagick provides many image manipulation commands.

I use the convert command here even though the ImageMagick docs mention the magick command. It turns out I don’t have the magick command on my system. This is due to me having an older version of ImageMagick (6.9.11-60 on Debian bullseye); the latest version, as of writing, is 7.1.1-43. If you want to use the legacy commands in the new version, it supports the old commands as sub-commands.

The first option to discuss is -resize, where we pass in our desired image size (1000x420). This option scales the input image to match the size we want for compatibility with dev.to.

Next is the -gravity option, which instructs ImageMagick where to place the input image on the output image canvas. The center option ensures that the input image is centred on the output image canvas both vertically and horizontally.

The final option is -extent, which sets the output image size. Although this sounds a lot like the -resize option, it’s not doing the same thing. -resize scales the input image up or down to the desired size. The -extent option sets the size of the canvas for the output image and hence the geometry of the image file written to disk.

As mentioned in the -extent docs, if the input image’s aspect ratio doesn’t exactly match that specified by the argument to -resize, then the image is centred (via the -gravity option) on a canvas of the size given by the argument to -extent. Because the canvas has a set size from -extent, ImageMagick is able to work out how much to pad the resized input image to create an output image of the desired dimensions.

Gravity goes in one direction

Note that the -gravity option has to come before the -extent option, as noted in a comment to the StackOverflow answer I mentioned earlier. This is because -gravity operates on the -geometry-like option that comes after it (in this case -extent). Thus, it must appear before the -extent option on the command line. If -gravity comes after -extent, then the image won’t be centred.

An example will hopefully make this clearer. Consider a 100x100 pixel black square. We can create this like so:

$ convert -size 100x100 'xc:rgb(0,0,0)' black-square.png

If we put -gravity on the command line before the -extent option

$ convert black-square.png \
    -resize 1000x420 -gravity center -extent 1000x420 \
    -border 10 \
    black-square-gravity-before-extent.png

we get what we expect:

Black square with white padded to each side from -gravity option appearing before -extent option

(Note that I’ve added a border around the image to more easily differentiate it from the surrounding page.)

In other words, ImageMagick has resized the square so that its largest dimension fits exactly within the -extent. The remaining dimension has been padded so that the output image has the dimensions specified by -extent.

However, if we put the -gravity option after the -extent option,

$ convert black-square.png \
    -resize 1000x420 -extent 1000x420 -gravity center \
    -border 10 \
    black-square-gravity-before-extent.png

the desired centering doesn’t happen, and the black square is padded only on the right with white:

Black square with white padded only on the right due to -gravity option appearing after -extent option

Even though the input image isn’t centred as we wished, the output image still has the correct geometry.

In other words, put your gravity around the right way!

devtoify

To reduce friction when creating cover images even more, I created an executable Bash script called devtoify in my ~/bin/ directory which handles everything for me. Here it is in all its glory:

#!/bin/bash

# resize and pad input image to match https://dev.to cover image size
# guidelines
if [ "$1" == "" ]
then
    echo "Usage: devtoify <input-image-filename>"
    exit 1
fi

# give input argument a nicer variable name
INPUT_IMAGE=$1

# extract file's basename and extension
# solution found here: https://stackoverflow.com/a/965072/10874800
INPUT_IMAGE_STEM="${INPUT_IMAGE%.*}"
INPUT_IMAGE_EXT="${INPUT_IMAGE##*.}"

# construct output image
OUTPUT_IMAGE="${INPUT_IMAGE_STEM}-cover.${INPUT_IMAGE_EXT}"

# resize and pad input image
CONVERT_ARGS="-resize 1000x420 -gravity center -extent 1000x420"
CMD="convert $INPUT_IMAGE $CONVERT_ARGS $OUTPUT_IMAGE"
$CMD  # run command constructed in $CMD

echo "Created $OUTPUT_IMAGE"

This way I now only need to run:

$ devtoify <input-image-filename>

to resize and pad my cover image to be compatible with the dev.to image size guidelines. Yay!

Wrapping up

To create dev.to-conformant cover images, don’t work too hard, just reach for ImageMagick!

  1. Why yes, I did boot my PowerBook 1400cs just so I could take a screenshot of this icon. 

Support

If you liked this post and want to see more, please buy me a coffee!

buy me a coffee logo