imagemagickluceecfexecute

What is the correct way to handle apostrophes in text in ImageMagick


I have a script that puts together ImageMagick command line commands to do processing on PDF documents. These end up being extremely long, but this is a representative example of one such command (line returns added for readability:

 magick.exe -density 300 -compress ZIP ( "c:\IMtemp\32.pdf[0]" -fill "#000" -stroke "#062430" -font Arial
 -pointsize 12 -draw "text 535,515 'This is my test text'") "c:\IMtemp\final.pdf"

That command works fine. However, the text is dynamic and comes from user input. If the user were to include an apostrophe, the command line would end up being:

 magick.exe -density 300 -compress ZIP ( "c:\IMtemp\32.pdf[0]" -fill "#000" -stroke "#062430" -font Arial
 -pointsize 12 -draw "text 535,515 'This is my test text; it's just great'") "c:\IMtemp\final.pdf"

This will fail, of course, because the apostrophe prematurely ends the text block. My first thought was to escape the apostrophe like this:

 magick.exe -density 300 -compress ZIP ( "c:\IMtemp\32.pdf[0]" -fill "#000" -stroke "#062430" -font Arial
 -pointsize 12 -draw "text 535,515 'This is my test text; it\'s just great'") "c:\IMtemp\final.pdf"

But that doesn't work. Instead the apostrophe is ignored, and the text "This is my test text; its just great" appears. So then I thought maybe I could use an alternative character and tried this:

 magick.exe -density 300 -compress ZIP ( "c:\IMtemp\32.pdf[0]" -fill "#000" -stroke "#062430" -font Arial
 -pointsize 12 -draw "text 535,515 'This is my test text; it’s just great'") "c:\IMtemp\final.pdf"

That results in the text "This is my test text; it’s just great", I assume because IM isn't defaulting to UTF-8. I read in the docs that this can be circumvented by providing codes to IM and tried:

 magick.exe -density 300 -compress ZIP ( "c:\IMtemp\32.pdf[0]" -fill "#000" -stroke "#062430" -font Arial
 -pointsize 12 -draw "text 535,515 'This is my test text; it\u2019s just great'") "c:\IMtemp\final.pdf"

 magick.exe -density 300 -compress ZIP ( "c:\IMtemp\32.pdf[0]" -fill "#000" -stroke "#062430" -font Arial
 -pointsize 12 -draw "text 535,515 'This is my test text; it\x{2019}s just great'") "c:\IMtemp\final.pdf"

But these just displayed everything after the backslash as plain text.

I don't care how apostrophes are preserved, as long as whatever is there looks correct enough to be human-readable and professional. How do I achieve this?

I'm running IM via cfExecute on a Lucee server (running on Windows / IIS).


Solution

  • You can avoid all issues with escaping and quoting by feeding the annotation text into ImagMagick from a file or from stdin. So, if you create a file, called say "annotation.txt" that contains:

    Weird stuff with ', @ and ".
    

    You can tell ImageMagick to read the annotation from that file (using @filename) and place it on your image like this:

    magick -size 640x240 xc:magenta -gravity center -pointsize 32 -annotate -40+90 @annotation.txt result.png
    

    enter image description here


    Likewise, if you want to pump the annotation into ImageMagick from some other command, you can tell ImageMagick to read its stdin like this:

    echo "Whatever @ '" | magick -size 640x240 xc:magenta -gravity center -pointsize 32 -annotate -40+90 @- result.png
    

    enter image description here


    As Fred kindly reminded me in the comments, you would need to ensure your policy.xml file permits this. Its location can be found with:

    identify -list configure | grep CONFIGURE_PATH
    

    More discussion about how to edit and security implications here.