39

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?

1
  • 2
    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 . Oct 19, 2014 at 0:29

6 Answers 6

51

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.

9
  • 2
    Better quality than GIMP on the second -- thanks! Oct 19, 2014 at 0:48
  • 5
    Method 1 generated a very fuzzy image, while method 2 worked perfectly. Jun 20, 2015 at 1:06
  • 5
    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. Oct 8, 2016 at 21:28
  • 4
    Both methods will rasterize the pdf, although the method #2 does it at a much higher resolution. So none of these methods are satisfying.
    – Ant
    Jan 29, 2017 at 16:47
  • 2
    Regarding Method #1, also see stackoverflow.com/questions/6605006/…
    – equaeghe
    Feb 20, 2017 at 22:21
24

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. Note the comment about removing the / before LeaveColorUnchanged.

9
  • 1
    This method works great, the pdf is not rasterized and text is conserved as text
    – Ant
    Jan 29, 2017 at 16:50
  • 5
    I tried using this to remove a transparency layer via flattening, but it did not work for me. Nov 6, 2018 at 21:13
  • It changed a font for me but otherwise much better resolution than the other proposed methods.
    – ste
    Aug 16, 2019 at 9:23
  • 3
    This did not work for me, I get "Unrecoverable error: rangecheck in .putdeviceprops". The ps2pdf solution above did work.
    – sebastian
    Mar 22, 2021 at 6:46
  • 1
    Got also "Unrecoverable error: rangecheck in .putdeviceprops". The ghostscript-answer from user107769 did work. Jun 20, 2021 at 20:26
13

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
2
  • 2
    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.
    – Jaydin
    Nov 19, 2020 at 0:16
  • 1
    Ya, ditto. Worked for me too.
    – Diagon
    May 11, 2023 at 22:03
3

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'
3
  • 1
    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"
    – Aidan Kane
    Jul 31, 2018 at 7:54
  • 3
    To be clear, this approach doesn't flatten transparent layers (as indicated above). Nov 6, 2018 at 21:15
  • This works awesome
    – Dan Ortega
    Dec 6, 2021 at 1:09
0

I frequently need to flatten PDFs or make them image-only. I wanted to do this quickly from within Nautilus instead of going to a terminal, so I created two Nautilus scripts based on the previous answers. I am sharing the instructions in case they are useful to others.

Create script to flatten PDFs:

  1. Go to the Nautilus script folder ~/.local/share/nautilus/scripts/
  2. Create a new shell script file (eg FlattenPDF.sh)
  3. Make this file executable (eg Natiuls PropertiesPermissionsAllow executing file as program)
  4. Insert below text into the file:

#!/bin/bash

# Flattend PDFs    

IFS='
'
for file in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
do
  if [ -f "$file" ]; then
    base=${file%.*}
    ext=${file##*.}
    newname=${base}_flat.pdf
    gs -dSAFER -dBATCH -dNOPAUSE -dNOCACHE -sDEVICE=pdfwrite -dPreserveAnnots=false -sOutputFile=$newname $file
  fi
done

Create script to create image-only (text not searchable or selectable) PDFs:

  1. Go to the Nautilus script folder ~/.local/share/nautilus/scripts/
  2. Create a new shell script file (eg ImageOnlyPDF.sh)
  3. Make this file executable (eg Natiuls PropertiesPermissionsAllow executing file as program)
  4. Insert below text into the file:

#!/bin/bash

# Image-only PDFs    

IFS='
'
for file in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
do
  if [ -f "$file" ]; then
    base=${file%.*}
    ext=${file##*.}
    newname=${base}_img.pdf
    gconvert -density 200 $file $newname
  fi
done

Restart nautilus (eg type nautilus -q to quit Nautilus and then open Nautilus from the Dash again). If you right-click on a file, you should see the Scripts menu with the new scripts.

0

The pdf2ps and ps2pdf method did not compress my file. So I invented my own way:

libreoffice --convert-to pdf:writer_pdf_Export --outdir /tmp/ input.pdf

You should see a factor of 5 reduction in space in the output file:

ls -lah /tmp/input.pdf

I tested it in CentOS 7 and 9 computers.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .