Making a PDF grayscale with ghostscript

A request from a friend made me face the problem of converting a color [[Portable Document Format|PDF]] into a [[grayscale]] one. Searching the web provided some ways of doing so with [[Adobe Acrobat]], via some obscure menu item somewhere.

However, the very same operation could be undertaken with free tools, such as [[ghostscript]]. I found a way to do it in the YANUB blog, and I will copy-paste it here, with a small modification.

Assuming we have a file called color.pdf, and we want to convert it into grayscale.pdf, we could run the following command (all in a single line, and omitting the “\” line continuation marks):

% gs -sOutputFile=grayscale.pdf -sDEVICE=pdfwrite \
-sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH color.pdf

I prefer the above to YANUB’s version below (in red what he lacks, in blue what I lack), because a shell operation is substituted by some option(s) of the command we are running:

% gs -sOutputFile=grayscale.pdf -sDEVICE=pdfwrite \
-sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH color.pdf < /dev/null

A sample [[Perl]] script to alleviate the tedious writing above:

#!/usr/bin/perl -w
use strict;
my $infile = $ARGV[0];
my $outfile = $infile;
$outfile =~ s/\.pdf$//;
$outfile = $outfile.”_gray.pdf”;
system “gs -sOutputFile=$outfile -sDEVICE=pdfwrite -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray -dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH $infile”

Assuming we call the Perl script “togray.pl”, and that we have a color file “input.pdf”, we could just issue the command:

% togray.pl input.pdf

and we would get a grayscale version of it, named “input_gray.pdf”.

27 Comments »

  1. Jose said,

    November 6, 2008 @ 4:19 am

    Hi,

    Great post and it also works in Windows with Ghostview (http://pages.cs.wisc.edu/~ghost/doc/GPL/gpl863.htm).

    The only thing that I had to change was the exe.

    gswin32.exe -sOutputFile=grayscale.pdf -sDEVICE=pdfwrite -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray -dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH color.pdf

    I did try the perl script but it should work also.

    Thanks,
    Jose.

  2. CC said,

    February 2, 2009 @ 13:07 pm

    Hello,

    this is very useful; I just have to add a couple of commands to go back to the EPS format without loss of quality.

    >> pdfcrop grayscale.pdf

    This command let you remove the white spaces around the picture (introduced with the previous command): this is particularly useful if you want to insert the picture into a LaTeX file. The standard output file name is grayscale-crop.pdf (the -crop part is added)

    >> pdftops -eps grayscale-crop.pdf final.eps

    Finally, you revert your pdf file to the original eps format.

    I searched for such a solution for a long time: I am going to add the whole tutorial to Goggle Knol, obviously citing this webpage: I hope it is convenient for you!

  3. isilanes said,

    February 2, 2009 @ 13:37 pm

    Thanks CC,

    The contents of my blog are licensed under a Creative Commons license (ups, I thought I had a tag somewhere, but now I only see the “Copyright (c) handyfloss 2009” at the bottom. I’ll add a CC tag some day), and you may use them any way you see fit, provided that you cite the source, and you make no commercial use of it.

    So, yes, putting it in Knol is fine with me. Actually I find it very flattering (and undeserved).

  4. CC said,

    February 2, 2009 @ 13:59 pm

    Well, this is the link:
    http://knol.google.com/k/c-c/how-to-convert-a-vector-eps-color/1yx5vp4cwri6n/2#

    It is not flattering nor undeserved: I only think it could be useful (it was for me) to publish this with the correct references.
    And then….. I was eager to try this Google Knol ;-)

  5. Julien said,

    October 29, 2010 @ 22:59 pm

    Thanks for the script, was really useful to me today!

  6. Marcello said,

    March 23, 2011 @ 10:28 am

    Hi, thanks for the script, but it doesn’t work for me. I have a PDF obtained from scanning a paper doc. Each page is composed of a single, full-page embedded jpeg (color) image.
    I still haven’t found a way to convert that file to grayscale without resorting to manual, single-image conversion.

    Thanks anyway. Page bookmarked.

  7. Marcello said,

    March 23, 2011 @ 10:36 am

    Sorry, my bad, I actually forgot the “=Gray” bit after -sColorConversionStragegy! Now it works like a charm, thank you!!

  8. Paul said,

    March 30, 2011 @ 11:55 am

    Hi! Great little script. Makes my live a lot easier when writing my thesis.

    Thanks,
    Paul

  9. Michael said,

    August 12, 2011 @ 14:18 pm

    Hi! Excellent work, thanks!

    However, I would need additional functionality as my target is to convert a PDF into black & white (monochrome). I would like to define a threshold – actually I am most interested in a threshold value of 100%: Black pixels (rather vectors) should remain black and everything that is not purely black should disappear (i.e. turn into white).

    The following link refers to similar ideas: http://www.rhinocerus.net/forum/lang-postscript/354259-using-ghostscript-convert-postscript-pure-black-white.html
    However, I cannot apply the parameters correctly.

    Could any of you gurus help me and provide a proper ghostscript command line that does the desired job?

    Many thanks in advance
    Michael

  10. isilanes said,

    August 16, 2011 @ 9:09 am

    Sorry Michael, I don’t know how to help you. The thread you link to contains a couple of interesting solutions. I understand that they didn’t work for you, in which case I really don’t have further ideas (even the ones in that thread were above me). Good luck!

  11. Jonas said,

    November 9, 2011 @ 14:38 pm

    Hi
    just what I want to do, but I get the error below. And I can’t figure out whats wrong.

    gs -sOutputFile=grayscale.pdf -sDEVICE=pdfwrite -sCCompatibilityLevel=1.5 -dProcessColorModel=/DeviceGray -sColorConversionStrategy=Gray -dNOPAUSE -dBATCH 03_00_00_551.pdf

    ESP Ghostscript 815.02 (2006-04-19)
    Copyright (C) 2004 artofcode LLC, Benicia, CA. All rights reserved.
    This software comes with NO WARRANTY: see the file PUBLIC for details.
    CRIT: rangecheck in .putdeviceprop

  12. mandev said,

    December 19, 2011 @ 14:11 pm

    @Jonas : -sCCompatibilityLevel=1.5 is wrong => -sCompatibilityLevel=1.5

  13. 2xJoe said,

    December 22, 2011 @ 11:53 am

    This hint was very usefull to me, thanx a lot!
    GS does the magic that corel and cs5 denied to me due to a obscure “host application error.”

  14. Sherilyn Muckelroy said,

    January 5, 2012 @ 9:37 am

    Thanks, bookmarked!

  15. hyangyt said,

    January 24, 2012 @ 14:35 pm

    Hi,

    is there any way to convert a pdf to pure black & white (monochrome) with ghostscript? Thanks.

  16. hyangyt said,

    January 24, 2012 @ 14:57 pm

    This code works fine(for major cases) (see http://superuser.com/questions/200378/converting-a-pdf-to-black-white-with-ghostscript)

    pdf2ps color.pdf color.ps

    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

    but how to convert color pdf to monochrome pdf directly(without converting it to ps first)?

  17. isilanes said,

    January 24, 2012 @ 16:16 pm

    Hi hyangyt,

    I can’t really help you. Is there any reason why PDF -> PS -> PDF is not acceptable for you?

    I have tried the code you show, and it actually works on PS files, but not PDFs (if we do not convert the input PDF to PS before applying gs, the output PDF is still a color one). It strikes me as funny, since gs should also handle PDFs!

    I must also say that your code seems to convert text to B/W, but not images, at least in a couple of tries I’ve made.

  18. hyangyt said,

    January 25, 2012 @ 4:28 am

    Hi,

    I found a way to do it, please see my post:

    http://yentaublog.wordpress.com/2012/01/25/convert-pdfs-to-blackwhite-translated-from-chinese/

  19. hyangyt said,

    January 25, 2012 @ 4:30 am

    It converts PDF to DJVU first, then convert to B&W PDF. It seems work much better and faster, and works for images, too.

  20. isilanes said,

    January 25, 2012 @ 9:34 am

    Thanks hyangyt! Very nice of you to share your solution.

  21. jan said,

    May 21, 2012 @ 1:08 am

    thanks for the summary of the gs commands!

    tiny comment on the perl script — if the file name doesn’t end with .pdf, the input file will be overwritten. it might be better to check and add _gray at the end anyway, even if there’s no .pdf ending.

  22. isilanes said,

    May 21, 2012 @ 8:39 am

    Hi jan,

    Thanks, your warning is so true! However, it a PDF without a .pdf ending is used, the user deserves whatever happens to it ;^)

    I’ll check it and fix it.

  23. Setting Color LaTeX Generated PDF To Print In Black & White | Click & Find Answer ! said,

    April 21, 2013 @ 16:14 pm

    […] black and white rather than greyscale.You can Ghostscript to convert a colour PDF to greyscale. See http://handyfloss.net/2008.09/making-a-pdf-grayscale-with-ghostscript/ .However, you’d get the same result just setting your printer settings to […]

  24. convert pdf to grayscale | Bitkorn Blog said,

    June 11, 2015 @ 9:30 am

    […] der Suche nach einer Lösung um PDF Dokumenten die Farbe zu nehmen fand ich diesen Blog. Es funktioniert […]

  25. Paul said,

    October 5, 2015 @ 13:10 pm

    Hey,

    first of all: Thanks!
    Is it possible to modify the pearl script that I can use it for a bunch of pdf files and don’t have to type in every single pdf file in a folder (maybe including subfolders)?

    Thanks again

    PS: I tried the command and the file size is not really smaller (max. 10%) I was assuming a higher reduction of the file size.

  26. isilanes said,

    October 5, 2015 @ 14:01 pm

    The following Python script will convert all PDF files in a directory into grayscale, if called from within that directory:

    import glob
    import subprocess as sp
    
    for fn_in in glob.glob("*.pdf"):
        fn_out = fn_in.replace(".pdf",'') + "_gray.pdf"
    
        string = '{0} -> {1}'.format(fn_in, fn_out)
        print(string)
        
        cmnd = "gs -sOutputFile={1} -sDEVICE=pdfwrite -sColorConversionStrategy=Gray\
     -dProcessColorModel=/DeviceGray -dCompatibilityLevel=1.5 -dNOPAUSE -dBATCH {0}".format(fn_in, fn_out)
        s = sp.Popen(cmnd, shell=True)
        s.communicate()
    
  27. Hervé said,

    April 15, 2020 @ 11:13 am

    Hi Handy,
    Thanks for this thread. Very usefull informations.
    Unfortunately, ghostscript does not provide a feature to convert all text in black (not grayscale).
    Today, I receive a pdf with title and sub-title in orange. I can’t read it on the grayscale printed version :-( . It’s to light / pale. Then I need to convert all text in black, and others like figures or pictures in gray scale.

RSS feed for comments on this post · TrackBack URI

Leave a Comment