Converting a PDF to black & white with ghostscript

42,860

Solution 1

The last suggestion indeed only converts to grayscale and then only works if the underlying doc uses setrgbcolor. This did not work for me, since I had a doc, that used setcolor.

I had success with redefining setcolor to always set the color to 0,0,0:

gs -o <output-file.pdf> -sDEVICE=pdfwrite \
-c "/osetcolor {/setcolor} bind def /setcolor {pop [0 0 0] osetcolor} def" \
-f <input-file.ps>

It has been 15+ years since I did any PostScript hacking, so the above may be lame, incorrect or even accidental - if you know how to do better, please suggest.

Solution 2

I am not sure if the following suggestion will work... but it may be worth to try out:

  1. convert the PDF to PostScript using the simple pdf2ps utility
  2. convert that PostScript back to PDF while using a re-defined /setrgbcolor PostScript operator

These are the commands:

First

  pdf2ps color.pdf color.ps

This gives you color.ps as output.

Second

gs \
-o bw-from-color.pdf \
-sDEVICE=pdfwrite \
-c "/setrgbcolor{0 mul 3 1 roll 0 mul 3 1 roll 0 mul 3 1 roll 0 mul add add setgray}def" \
-f color.ps

Solution 3

It's not ghostscript, but with imagemagick this is quite simple:

 convert -monochrome input.pdf output.pdf

Solution 4

I could not find out which procedure for color selection is used in the PDFs I am dealing with. This is why I convert to grayscale PostScript first:

gs -o gray.ps -sDEVICE=ps2write -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray -dCompatibilityLevel=1.4 -f colored.pdf

As the PDFs I struggle to print may contain confidential information which is cleverly "redacted" by having the color set to white, I need to employ some sort of thresholding. This is what I came up with:

gs -o thresholded.pdf -sDEVICE=pdfwrite -c "/osetgray {setgray} bind def /setgray {0.5 lt {0} {1} ifelse osetgray} def" -f gray.ps

For those (like me) unfamiliar with PostScript's stack programming style, this re-defines setgray as:

setgray(value) {
   original_setgray(value < 0.5 ? 0 : 1)
}

Solution 5

for gray scale PDF:

By using GhostScript

IN PHP code, use this script

exec("'gs' '-sOutputFile=outputfilename.pdf' '-sDEVICE=pdfwrite' '-sColorConversionStrategy=Gray' '-dProcessColorModel=/DeviceGray' '-dCompatibilityLevel=1.4'  'inputfilename.pdf'",$output);

usefull url
http://www.linuxjournal.com/content/tech-tip-using-ghostscript-convert-and-combine-files

Share:
42,860

Related videos on Youtube

niklasfi
Author by

niklasfi

I like vb and c#

Updated on September 17, 2022

Comments

  • niklasfi
    niklasfi over 1 year

    Similarly to this question:

    Convert a PDF to greyscale on the command line in FLOSS?

    I have a PDF-document and want to convert it to pure black and white. So I want to discard halftones. To convert to grayscale with ghostscript I can use this command:

    gs \
     -sOutputFile=output.PDF \
     -sDEVICE=pdfwrite \
     -sColorConversionStrategy=Gray \
     -dProcessColorModel=/DeviceGray \
     -dCompatibilityLevel=1.4 \
      input.PDF < /dev/null
    

    What do I have to change to get monochrome e.g. only the colors black and white and no halftones?

  • frabjous
    frabjous over 13 years
    I tried this and was still left with shades of gray. niklasfi wants monochrome.
  • akhil411
    akhil411 almost 11 years
    The resulting pdf quality is much much worse than original.
  • Ilia w495 Nikitin
    Ilia w495 Nikitin over 6 years
    convert -monochrome -denisty 600 ?
  • Gavin S. Yancey
    Gavin S. Yancey over 5 years
    This seems to do halftoning; I want all colors (but white) to be converted to black, regardless of darkness.
  • Massimo
    Massimo over 4 years
    Ghostscript 9.50 complains "Unknown device: psmono"
  • Hermann
    Hermann over 3 years
    It should be {setcolor} rather than {/setcolor} since PostScript uses no slash when procedures are called during bind. Other than that: Great answer – thank you.
  • Hermann
    Hermann over 3 years
    Note: Recent versions of ghostscript do no longer include the now-deprecated pswriter (and variants like psmono): ghostscript.com/doc/9.26/VectorDevices.htm
  • XavierStuvw
    XavierStuvw about 3 years
    It did not work for me with gs 9.26. The output was in color, regardless of whether the argument was {setcolor} or {/setcolor} as per Hermann's comment above.
  • XavierStuvw
    XavierStuvw about 3 years
    I found pdf2ps incredibly slower than a conversion with gs.
  • XavierStuvw
    XavierStuvw about 3 years
    Does not work with gs 9.26 (for Linux)
  • XavierStuvw
    XavierStuvw about 3 years
    Re the issue with psmono device, see Hermann's note in the other answer superuser.com/a/479933/491642
  • 0range
    0range over 2 years
    Besides the issues with the quality, this does not seem to work any longer. As of 2021 this appears to produce fully colored pdfs just like the original.
  • 0range
    0range over 2 years
    I concur with @XavierStuvw It seems the behavior of gs has changed since 2011. The solution by @KurtPfeifle below that converts a ps to a black-white pdf with gs ... -c "/setrgbcolor{0 ... still works, however.