Making Maps, Version 1.5: AutoTrim and Border with Imagemagick

Map of the day's travels in my first day in the blue temple.

Map of the day’s travels in my first day in the blue temple.

I did finally figure out how to update the map making process with ImageMagick. Not the whole process. I am still using Pages for the initial layout and export to PDF, which is why I am calling this v1.5 rather than v2.0

The trick is to cd to the directory with the exported PDF, and, use the following command

convert \( -density 250 Day40b.pdf -fuzz 1% -trim \) -bordercolor white -border 20x20 +repage Day40b.png

A good 3 minutes of time saved? I’ll be making a lot of maps. I think it is worth it.

I’m not versed enough in ImageMagick to have just written that line directly. I had to back my way into a problem. In my manual process the last thing I do is trim the .png to have a little bit of white space around the edges. It is surprisingly tedious to eyeball that. Replacing that alone would have been enough. Once that problem was solved I slowly edged my way through the process towards PDF to png conversion.

For those who want to know, the following are the interim steps I took to build up the new command.

Step 1: Learn to trim

convert input_image.png -fuzz 1% -trim +repage output_image.png

A simple answer to how to trim an image. There was -trim, -chop, -shave. It was all a bit annoying to sort out. -trim is what detects the color of the corner and then removes the border accordingly. -fuzz gives -trim a little wiggle room. -trim can also be told what color to lop off explicitly. It took me awhile to find the official -trim documentation.

Step 2: Learn to add a border to trimmed image

convert input_image.png -bordercolor white -border 20x20 +repage output_image.png

The gist of which found on a forum topic promisingly titledtrim image whitespace but leave 30 pixel.

Step 3: Trim and border together

Sadly the link in the last step didn’t have the combo code I was looking for. I’d been seeing parenthesis in example code. Turns out they work kinda like parenthesis in math. (PPMDAS, PEMDAS for the kids.)

convert \( input_image.png -fuzz 1% -trim \) -bordercolor white -border 20x20 +repage output_image.png

Step 4: Convert from PDF test

 convert -density 250 input_image.pdf output_image.png

For me this line of code through an error. Specifically

convert: no images defined `test.png' @ error/convert.c/ConvertImageCommand/3187.

StackOverflow had the fix for this no images defined error message.

The fix was to install ghostscript, a PostScript interpreter, via the shell.

brew update
brew doctor
brew install ghostscript

Once ghostscript was installed that earlier line worked just fine.

Step 5: Combine all the ingredients

And this is what brings us to the final script.

Honest, first I did

convert \( \( -density 250 input_image.pdf \) -fuzz 1% -trim \) -bordercolor white -border 20x20 +repage output_image.png

But then I wanted to try simplifying one of the nested parentheses.

convert \( -density 250 input_image.pdf -fuzz 1% -trim \) -bordercolor white -border 20x20 +repage output_image.png

In a little more research, for what I’m doing there does not seem to be a detectable difference between the above and putting the -trim before the input image call and after (below). I wonder if there is one.

convert \( -trim -density 250 input_image.pdf \) -bordercolor white -border 20x20 +repage output_image.png

Perhaps if I begging doing batch processes it will see a speed bump?

Step 6: Create a batch process script to update older images

So, I wondered, what would it take to batch process the older maps so they all had a consistent border? I wasn’t planning to re-upload the images, but I was curious because I had some days’ maps laid out that I hadn’t written the posts for.  Would it be possible to do them all at once?

It is 100% legitimate to use mogrify for many many things. But apparently when you start building up complex calls, mogrify starts to fall short of it’s buddy convert. Since I want to preserve my original files anyway, a batch processing script seemed the order of the day.

If shell scripting is a totally new concept, the Apple Developer site has a nice primer for folks new to shell scripts, but not necessarily new to programing I’d say. Idiomatic mannerism abound in shell scripts. I can’t recommend it as your first programing experience unless creating automated processes on your computer is what drives you. If you want to be able to do more in a *nix environment in general, though that is never a bad thing. Here is a basic tutorial that seems broken down into smaller pieces, although it is relatively older. But then so is shell scripting.

I’m sure there is a way to attach this to a service via Apple Automator, but I’m just not sure I’ll be using it often enough. This effort was more about learning to batch process with Imagemagick in general than just this task.

Links I referenced:

The below file mostly works.  There seems to be trouble with some of the Pages created PDF files. Sometimes they throw an error, sometimes they don’t. Quitting Pages, copying the table with the map in it to a new file, making a PDF from that file seems to do the trick… sometimes.  I will be abandoning that step of the process as soon as possible so I’m not going to sweat the PDF standards error for now. PDFs are kind of a messy beast, and if I can run screaming, I will.

#based on code found here:
#This script takes an image with a lot of extra border, trims it down
#and then re-adds a 20 pixel border evenly around the edge.
#the tiles will be put in a directory called…
#If the destination folder doesn't exist, make it.
if [ ! -d ./${MYDIR} ]; then mkdir ./${MYDIR}; fi
# processes all pngs
#if there are png files found, then for each of them
if ls | grep png; then for p in *.png; do
echo "Processing $p"
#Trim it, then add a border,
#then save it to a new directory with an
#appended file name.
convert \( $p -fuzz 1% -trim \) \
-bordercolor white -border 20×20 +repage \
#process all the PDFs
#if there are pdf files found, then for each of them
if ls | grep pdf; then for d in *.pdf; do
echo "Processing $d"
#Open it at an image density of 250px/in,
#trim it, then add a border.
#Save it to a new directory with an
#appended file name.
convert \( \( -density 250 $d \) -fuzz 1% -trim \) \
-bordercolor white -border 20×20 +repage \

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s