Is there a way to flatten a .pdf image from the command line?

26,038

Solution 1

I found these 2 method via Google, in this thread titled: Re: Flattening PDF Files at the UNIX Command Line.

Method #1 - using Imagemagick's convert:
$ convert -density 300 orig.pdf flattened.pdf 

NOTE: The quality is reported to be so so with this approach.

Method #2 - Using pdf2ps -> ps2pdf:
$ pdf2ps orig.pdf - | ps2pdf - flattened.pdf

NOTE: This method is reported to retain the image quality.

Solution 2

Ghostscript (gs) worked better than pdf2ps and convert for me. Quality was hardly degraded and file size is small.

gs -dSAFER -dBATCH -dNOPAUSE -dNOCACHE -sDEVICE=pdfwrite \
-sColorConversionStrategy=/LeaveColorUnchanged  \
-dAutoFilterColorImages=true \
-dAutoFilterGrayImages=true \
-dDownsampleMonoImages=true \
-dDownsampleGrayImages=true \
-dDownsampleColorImages=true \
-sOutputFile=document_flat.pdf document_original.pdf

Found here: http://zeroset.mnim.org/2015/01/07/flatten-pdfs-with-ghostscript/

Solution 3

ghostscript changed their default for flattening annotations in late 2016.

To simply flatten a PDF now, you need -dPreserveAnnots=false

So a simple command line is now

gs -dSAFER -dBATCH -dNOPAUSE -dNOCACHE -sDEVICE=pdfwrite \
-dPreserveAnnots=false \
-sOutputFile=document_flat.pdf document_original.pdf

Solution 4

Although convert will keep the same file size I've found it to be slow.

The pdf2ps ps2pdf method is faster but I noticed for me it was increasing the file size.

pdftk is nice because it is not only fast but also retains a similar file size.

This is what I use to bulk flatten a directory.

    function pdfflatten () {
        pdftk "$1" output "$2" flatten
    }
    export pdfflatten
    alias pdfflattenDIR='mkdir flattenedPDFs; for i in `seq $(ls *.pdf | wc -l)`; do a=`ls *.pdf | head -$i | tail -1`; pdfflatten "$a" flattenedPDFs/"$a"; done'
Share:
26,038

Related videos on Youtube

generic_user
Author by

generic_user

Updated on September 18, 2022

Comments

  • generic_user
    generic_user over 1 year

    In GIMP, I can import a PDF, and use the GUI to flatten it (if it was made with many layers) by selecting Flatten Image in the Image dropdown menu. I can then export the PDF with a new filename.

    I would like to automate this. Is there some way to do it via the terminal?

    • PersianGulf
      PersianGulf over 9 years
      install imagemagick and read man mogrify-im6 , montage-im6 , display-im6 , stream-im6 , identify-im6 , import-im6 , conjure-im6, composite-im6 , convert-im6 , animate-im6 and compare-im6 .
  • generic_user
    generic_user over 9 years
    Better quality than GIMP on the second -- thanks!
  • slm
    slm over 9 years
    @ACD - that's good to know. Glad it solved your Q.
  • eacousineau
    eacousineau over 7 years
    Unfortunately, Method #2 does not rasterize the image, so if you are trying to block out sensitive portions, a user could still open the document and remove layers (with something like Inkscape). You can, however, modify the resolution of Method #1: $ convert -density 150 {original,flattened}.pdf If you need to preserve disk space, you can use -type Grayscale or -monochrome or things of that sort.
  • bksoares
    bksoares over 7 years
    Both methods will rasterize the pdf, although the method #2 does it at a much higher resolution. So none of these methods are satisfying.
  • bksoares
    bksoares over 7 years
    This method works great, the pdf is not rasterized and text is conserved as text
  • equaeghe
    equaeghe about 7 years
    Regarding Method #1, also see stackoverflow.com/questions/6605006/…
  • Aidan Kane
    Aidan Kane almost 6 years
    pdftk flatten does not change the images within a PDF. From the docs it "merges an input PDF’s interactive form fields (and their data) with the PDF’s pages"
  • mikemtnbikes
    mikemtnbikes over 5 years
    I tried using this to remove a transparency layer via flattening, but it did not work for me.
  • mikemtnbikes
    mikemtnbikes over 5 years
    To be clear, this approach doesn't flatten transparent layers (as indicated above).
  • ste
    ste over 4 years
    It changed a font for me but otherwise much better resolution than the other proposed methods.
  • Alexus
    Alexus about 4 years
    I'm using this for resizing notes. Method 2 took ages to convert 12 pages from 2 MB to 70 MB (pdf->ps) and back (ps -> pdf). Ghostscript did it faster.
  • Alexus
    Alexus about 4 years
    Is there a way to do this with batch files in place?
  • carter
    carter over 3 years
    When I run the convert command I get an error. My PDF is only text, no images. error: convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/562. convert: no images defined `no_protect_raster.pdf' @ error/convert.c/ConvertImageCommand/3285.
  • Kayofeld
    Kayofeld over 3 years
    The second method increase the size of my PDF more than 10x, and lost text highlighting annotation created with Evince.
  • JayDin
    JayDin over 3 years
    Thanks, worked well for me. This command seems to give the same output as Stan Bondi's answer while being simpler. Both were much quicker and gave a smaller file than using convert.
  • sebastian
    sebastian about 3 years
    This did not work for me, I get "Unrecoverable error: rangecheck in .putdeviceprops". The ps2pdf solution above did work.
  • andreas1724
    andreas1724 almost 3 years
    Got also "Unrecoverable error: rangecheck in .putdeviceprops". The ghostscript-answer from user107769 did work.
  • Dan Ortega
    Dan Ortega over 2 years
    This works awesome