Nicholas
Nicholas

Reputation: 2060

imageMagick: How do I draw on one page of a pdf but keep the whole pdf?

I have a web app running on Lucee 5.3.7.47. cfPDF is, unfortunately, not particularly stable in this version, and so I've decided to try to use ImageMagick to handle my PDF functions, which essentially amount to adding text and an image to a pdf file.

I have a 5 page PDF that I'm using to test. I'm trying to add some text to page 5 of that pdf using this command:

magick.exe -density 300 "c:\test.pdf[4]" -pointsize 12 -draw "text 25,425 'Test text'" -draw "text 362,425 'Test text 2'" c:\test_final.pdf

This works for me almost perfectly, in that the text appears exactly where I want it in test_final.pdf. However, there are two issues:

  1. My 126kb PDF becomes a 900kb PDF
  2. My new pdf has only a single page: page 5 of the original

I assume issue 1 is because ImageMagick can't draw on a pdf without rasterizing all the text, forcing the entire PDF to be saved essentially as an image. This is very undesirable, but I can live with it unless there's a better way in IM.

Issue 2, obviously, is a deal breaker. I need all pages of the original PDF to remain intact, but I only want to draw the text on one particular page. How do I do this?

Removing the page identifier after the pdf name results in a 5-page pdf file, but my text is drawn on every page.

I thought that maybe specifying the other pages of the pdf before the fifth would cause an append operation, but with this command I still see the text drawn on every page:

magick.exe -density 300 "c:\test.pdf[0-3]" "c:\test.pdf[4]" -pointsize 12 -draw "text 25,425 'Test text'" -draw "text 362,425 'Test text 2'" c:\test_final.pdf

EDIT

Per a comment, I tried to look up how to do parenthesis processing. It led me to someone asking for something similar here, with a solution based off the docs here.

I tried coming up with a similar command using magick.exe:

-density 300 -compress ZIP "c:\test.pdf[0-3]" \( -clone 4 -pointsize 12 -draw "text 25,425 'Test text'" -draw "text 362,425 'Test text 2'" \) -delete 4 -insert 4 "c:\test_final.pdf"

Finding the compress options helped reduce the file size considerably when added to the original command. However, this new command comes back with:

magick.exe: unable to open image '\(': No such file or directory @ error/blob.c/OpenBlob/3537.
magick.exe: no decode delegate for this image format `' @ error/constitute.c/ReadImage/572.

I assume this is an error with my command, and not with any missing dependencies, since it was able to open, edit, and save the file using my original commands.

Upvotes: 0

Views: 463

Answers (1)

Nicholas
Nicholas

Reputation: 2060

With fmw42's guidance, I was able to formulate a working IM command that accomplishes what I want to accomplish (line breaks added for readability):

 -density 300 -compress ZIP "c:\test.pdf[0-3]"
 ( "c:\test.pdf[4]" -font Segoe-Script -pointsize 12 -draw "text 161,1615 'Test Text 1'"
 -font Arial -draw "text 1712,1619 'Test Text 2'" )
 "c:\test_final.pdf"

Some description of what this command is doing, to the best of my understanding:

  • -density 300 sets the dpi to 300; multiplied by the pdf page size in inches gives the resolution of that page
  • -compress ZIP makes the resulting pdf smaller by losslessly compressing the images for each page
  • "c:\test.pdf[0-3]" tells IM to start by using pages 1-4 of the original pdf
  • the parens command is processed seperately, with everything in it happening only to the page specified within (in this case page 5)
    • "c:\test.pdf[4]" indicates that we're taking page 5 of the original pdf and working with that.
    • -font Segoe-Script -pointsize 12 sets the font details for the next command
    • -draw "text 161,1615 'Test Text 1'" writes the text 'Test Text 1' at coordinates 161, 1615, which I calculated using the page size and density as mentioned above.
    • -font Arial allowed me to change the font face mid-command for the second piece of text
    • -draw "text 1712,1619 'Test Text 2'" wrote some more text on this page, this time in a different font.
  • "c:\test_final.pdf" tells IM that after it takes pages 1-4 from the first section, and adds page 5 from the parens, it should create the output file test_final.pdf

This is not a perfect solution for me. Even though the zip compression decreased the output file size considerably, all pages were still rasterized. This caused an increase in file size: 126kb > 831kb. Unfortunately, I don't think this can be helped with IM, and given that we're still under a MB it could be worse.

I hope this helps someone else hoping to do something similar.

Upvotes: 1

Related Questions