Imagemagick uses the convert shell command to convert various file formats back and forth. When it is used to convert pdf to png/jpg, it delegates this task to ghostscript (gs command on shell) to do the conversion.

One might think they both should take the same time to complete task but imagemagick limits user in the settings that can be passed to gs and it does extra work while passing the jobs to ghostscript.

ImageMagick loads the entire pdf into the memory before process it. On the other hand ghostscript has the capability of processing 1 page at time which reduces the load on hardware by a lot. Here is a great article about that i used as a reference in this testing.

I must mention few background info on the specs:

  • ImageMagick version:  ImageMagick 6.7.7-10 2013-02-25 Q16
  • GhostScript version: 9.07
  • Intel(R) Core(TM) i7-2670QM CPU @ 2.20GHz and 8GB ram

I used a sample PDF file with following meta info:

Tagged:      no
Form:        none
Pages:       832
Encrypted:   no
Page size:   362.835 x 272.126 pts
Page rot:    0
File size:   14986182 bytes
Optimized:   no
PDF version: 1.4

RESULTS

Using convert to convert from PDF to PNG, with 300 density: it took 426 seconds and 51mb

Using gs to convert from PDF to PNG, with 300 density: it took 135 seconds and  39mb disk space

Also I have achieved further time improvement by using jpeg, Using gs to convert from PDF to JPEG with 300 density and 100% quality: it took 32 seconds and 153mb disk space

CODE

These are the shell scripts I have used for my benchmarking: For PDF to PNG

#!/bin/bash
START=$(date +%s)

pageNum=`gs -q -dNODISPLAY -c "(./test.pdf) (r) file runpdfbegin pdfpagecount = quit"`
gs -dNumRenderingThreads=4 -dNOPAUSE -sDEVICE=pngalpha -dFirstPage=1 -dLastPage=$pageNum -sOutputFile=./output/image%d.png -r300 -q test.pdf -c quit

END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

For PDF to JPEG

#!/bin/bash
START=$(date +%s)

pageNum=`gs -q -dNODISPLAY -c "(./test.pdf) (r) file runpdfbegin pdfpagecount = quit"`
gs -dNumRenderingThreads=4 -dNOPAUSE -sDEVICE=jpeg -dFirstPage=1 -dLastPage=$pageNum -sOutputFile=./output/image%d.jpg -dJPEGQ=100 -r300 -q test.pdf -c quit

END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

For PDF to PNG

#!/bin/bash
START=$(date +%s)

convert -density 300 test.pdf test.png

END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

Although I must mention that I couldn’t get multi-threading working for ghostscript, I left the multi-threaded option in the code for those who might have ghostscript installed properly and has the multi-threading enabled.