How to batch convert PostScript files to PNGs via folder action with use of ImageMagick

1.1k views Asked by At

I'm trying to assign a folder action to the a folder with PS files that would automatically convert the PS files droppped in the folder to the PNG files. My shell script looks like follow:

for img in "$@"; do
    filename = ${img%.*}
    convert "$img" -background white -flatten "$filename.png"
done

and settings for my Automator folder action are provided in the screenshot below

Automator screenshot

I'm experiencing two problems:

  • When I drop *.ps files onto the folder the Automator action starts but does not produce files. I'm guessing the the problem is concerned with not passing the file name to the Shell Script but I'm not able to find solution to this.
  • When I attempt to execute the conversion directly from the terminal with use of the command: convert b.ps b.png the produced image is cut, like in the screenshot below Cut image after conversion.

I would like to fix so the Automator action: - Takes all the files that I decide to specify via the Filter Finder Items option - Converts them to high resolution, quality PNGs respecting the original PS file sizes (without cutting them or providing extra margins)

1

There are 1 answers

10
Kurt Pfeifle On

(You should spell out clearly in your question, that you are working on Mac OSX.)


You may have encountered a bug in ImageMagick when it comes to converting PS files (see also this discussion in the IM forum about it). Try to add -verbose to your convert command to see what exactly goes on.

Fact is, that ImageMagick cannot by itself consume PostScript (or PDF) input. It has to employ a delegate to do that for you -- and that delegate usually is Ghostscript.

It's a better approach for your task if you made your shell script differentiate between different input types: if you get PS or PDF, let Ghostscript do the job directly:

gs                     \
 -o output.png         \
 -sDEVICE=pngalpha     \
 -dAlignToPixels=0     \
 -dGridFitTT=2         \
 -dTextAlphaBits=4     \
 -dGraphicsAlphaBits=4 \
 -r72x72               \
  input.ps-or-pdf

Should you need further post-processing of the generated output.png (such as making the background white instead of transparent you could pipe the output to an ImageMagick convert-command now....


Update

Since it has been asked in a comment: if you want to use the same filename for output, but replace the .ps suffix by a .png suffix, use this Bashism:

inputfilename=../somedir/somefile.ps

gs                             \
  -o ${inputfilename/.ps/.png} \
  -sDEVICE=pngalpha            \
  -dAlignToPixels=0            \
  -dGridFitTT=2                \
  -dTextAlphaBits=4            \
  -dGraphicsAlphaBits=4        \
  -r72x72                      \
   ${inputfilename}

or this one

 -o $(dirname ${inputfilename})/$(basename ${inputfilename}).png

Both will allow you to keep the original directory (in case your 'inputfilename' includes an absolute or relative path). The first one is not as flexible with the input file's suffix: it works only for .ps -- for PDF you'd get a .pdf.png suffix...

Update 2

First determine which is the real BoundingBox covered by the original PostScript. This is different from the declared BoundingBox, that may (or may not!) be stated in a %%BoundingBox line of the PostScript code. Ghostscript's -sDEVICE=bbox will do that for you:

 gs -q -o - -sDEVICE=bbox a.ps

   %%BoundingBox: 102 118 866 698
   %%HiResBoundingBox: 102.257997 118.502434 865.278747 697.013979

Now you can use this info to determine how many pixels horizontally and how many pixels vertically you want the PNG output file to be sized. I'll pick 940 pixels wide and 760 pixels high (to allow for some margin around the output. Use -g940x760 with Ghostscript to set this as the page size:

inputfilename=a.ps

gs                             \
  -o ${inputfilename/.ps/.png} \
  -sDEVICE=pngalpha            \
  -dAlignToPixels=0            \
  -dGridFitTT=2                \
  -dTextAlphaBits=4            \
  -dGraphicsAlphaBits=4        \
  -g940x760                    \
   ${inputfilename}

The output is here:

940x760 pixels PNG created from PS input