ImageMagick / convert / --no-globbing!

barbie on 2009-09-30T12:19:59

I've recently reworked an image creation script at work to use ImageMagick's own convert script. The main reason being that text support is much better using convert than calling ImageMagick through its Perl API. However, it threw up a rather confusing issue, that has taken a while to track down and resolve.

The command issued for a number of images is along the lines of the following:

convert -background "#ffffff" -fill "#000000" -font Helvetica -pointsize 14 -size 400x caption:"*" 9780596001735.png

The 'caption' is the piece of text we wish to have in the image. In most cases this is 1 or 2 short sentences, but in some cases it can include a single asterisk, as above. This has the confusing result of creating many files with the text in each a different file name as found in the current directory. It's perhaps not too confusing to realise that filename expansion has occurred. However, the asterisk is quoted, so shouldn't be expanded by bash. After a bit of investigation and various attempts to check quoting in the shell, I discovered that ImageMagick's own documentation has this to say regarding convert...

In Unix shells, certain characters such as the asterisk (*) and question mark (?) automagically cause lists of filenames to be generated based on pattern matches. This feature is known as globbing. ImageMagick supports filename globbing for systems, such as Windows, that does not natively support it. For example, suppose you want to convert 1.jpg, 2.jpg, 3.jpg, 4.jpg, and 5.jpg in your current directory to a GIF animation. You can conveniently refer to all of the JPEG files with this command:

$magick> convert *.jpg images.gif

In the above command this would actually be expanded by the shell on Unix like systems, not convert, as there is no quoting around the asterisk. However, ImageMagick in its desire to be "helpful" gleefully ignores any quoting and does the filename expansion (or globbing as they call it) regardless. Hence why in my original command several hundred files could be generated.

Understanding this, I then set about trying to pass the character in hex form, escaping with '\' and quoting in a variety of ways to just get the single asterisk written as the text, all to no avail. I hunted through the online documentation (both on ImageMagick's site and in other forums) to find a solution, but drew a blank. I had expected to find a command-line option such as '--no-globbing' or similar, that would suppress the filename expansion feature, but alas no.

Through a bit of trial and error I finally discovered the solution:

convert -background "#ffffff" -fill "#000000" -font Helvetica -pointsize 14 -size 400x caption:"* " 9780596001735.png

Can you see the difference? All it took was a magic(k?) space character after the asterisk for convert to suppress the filename expansion!

Nowhere in the manual, docs and online help is there any mention of this. Perhaps I'm the first to encounter this, but I doubt it. As a way to help others who might also come across this frustration, I'm posting it here. I've submitted a bug report to the ImageMagick Wizards, so hopefully it may get considered for a future release. However, for now this looks to be the only way to get it working as intended.


Is the space magic?

grantm on 2009-09-30T20:20:20

Is the space actually 'magic' or it simply that you have no filenames that end with a space?

Re:Is the space magic?

barbie on 2009-10-01T12:16:20

ssshh! That's part of the magic ;)

From what I can see, that quite possibly is the reason.

Re:

Abigail on 2009-09-30T22:34:52

That works until you have a file whose name ends with a space. Another way:

(mkdir X; cd X; convert -background "#ffffff" -fill "#000000" -font Helvetica -pointsize 14 -size 400x caption:"*" ../your-file.png; cd ..; rmdir X)

This uses the fact that in an empty directory, a globbed '*' is just a '*'.

Re:

barbie on 2009-10-01T12:18:24

Except I'd rather not have odd directories being created, especially if anything goes wrong. Plus it seems a lot more work than the "magic" space :)

Re:

Abigail on 2009-09-30T22:37:27

Duh. Much simpler:

convert -background "#ffffff" -fill "#000000" -font Helvetica -pointsize 14 -size 400x caption:"'*'" your-file.png

The shell eats the double quotes, and convert gets the single quotes.

Re:

Abigail on 2009-09-30T22:39:00

Or even:

convert -background "#ffffff" -fill "#000000" -font Helvetica -pointsize 14 -size 400x caption:\"*\" your-file.png

Re:

barbie on 2009-10-01T12:23:11

As I mentioned, I did try all types of escaping and quoting. In your examples the images contain the 3 characters '*' and "*" respectively as the text. Infuriating! Even trying to fool it with the hex value doesn't work, it gets translated into an asterisk, then 'convert' does the filename expansion on it!