AMER
AMER

Reputation: 1001

Cropping a PDF using Ghostscript 9.01

I am not a programmer, but would like to learn how to crop a PDF using Ghostscript.

I have installed Ghostscript 9.01 in my machine.

Please guide me step by step process (starting from invoking Ghostscript) to crop a PDF with the specific coordinates.

I am even new to Ghostscript.

Upvotes: 52

Views: 54799

Answers (4)

Félix Paradis
Félix Paradis

Reputation: 6071

I started by getting the dimensions of my file with

gs -q -dBATCH -dNOPAUSE -sDEVICE=bbox myFile.pdf

Which outputs something like this for every page in the PDF

%%BoundingBox: 16 14 585 781
%%HiResBoundingBox: 16.991999 14.904000 584.207068 780.500015

Then, based on those values, I ran this second command to crop all pages

gs -o cropped.pdf -sDEVICE=pdfwrite -dDEVICEWIDTHPOINTS=430 -dDEVICEHEIGHTPOINTS=781 -dFIXEDMEDIA -f myFile.pdf

Using GhostScript 10.02.1

gs --version
10.02.1

Upvotes: 0

K J
K J

Reputation: 11940

Both previous answers just change the /CropBox view port of a file not actually crop a PDF content let me explain pictorially. Using one of the commands from previous answer to "Crop" the GhostScript supplied "Escher" Sample. We might note that the amount of "crop" in the result here on the left is aggressive and "cuts" the contents.

enter image description here

That is not so, the content is still there and we can use autocrop to restore the source image. so "crop" box is a re-movable viewport into the MediaBox.

To physically "Trim" a PDF (similar to redact all 4 sides) we need to use a function such as MuPDF mutool "trim" command.

Upvotes: 0

Lucas Belfanti
Lucas Belfanti

Reputation: 283

If someone is looking for a script to do it, I created a bash function for this:

function crop_pdf() {
    input=$1
    output=$6

    pdf_info=$(pdfinfo -box $input)
    currentWidth=$(echo "$pdf_info" | grep "Page size:" | awk '{print $3}')
    currentHeight=$(echo "$pdf_info" | grep "Page size:" | awk '{print $5}')

    left=$2
    bottom=$3
    right=$(echo "$currentWidth - $4" | bc)
    top=$(echo "$currentHeight - $5" | bc)

    gs -o $output -sDEVICE=pdfwrite -c "[/CropBox [$left $bottom $right $top] /PAGES pdfmark" -f $input
}

The usage is simple:

crop_pdf input.pdf left bottom right top output.pdf

For example:

crop_pdf mypdf.pdf 20 30 10 33 mypdf-cropped.pdf

In this example the command will remove 20 points from the left, 30 from the bottom, 10 from the right and 33 from the top.

"Points" is the measure explained above in the Kurt Pfeifle's answer.

I'm not 100% sure if it works with all the pdfs, but I think it could work.

This script needs the following:

Upvotes: 2

Kurt Pfeifle
Kurt Pfeifle

Reputation: 90335

First, take note that the measurement unit for PDF is the same as for PostScript: it's called a point [pt].

72 points == 1 inch == 25.4 millimeters

Assuming you have a page size of A4. Then the media dimensions are:

595 points width  == 210 millimeters
842 points height == 297 millimeters

Assuming you want to crop off:

   left edge: 24 points == 1/3 inch ~=  8.5 millimeters
  right edge: 36 points == 1/2 inch ~= 12.7 millimeters
    top edge: 48 points == 2/3 inch ~= 17.0 millimeters
 bottom edge: 72 points ==   1 inch ~= 25.4 millimeters

Then your Ghostscript commandline is this (on Windows):

gswin32c.exe                     ^
  -o cropped.pdf                 ^
  -sDEVICE=pdfwrite              ^
  -c "[/CropBox [24 72 559 794]" ^
  -c " /PAGES pdfmark"           ^
  -f uncropped-input.pdf

Or on Linux:

gs                               \
  -o cropped.pdf                 \
  -sDEVICE=pdfwrite              \
  -c "[/CropBox [24 72 559 794]" \
  -c " /PAGES pdfmark"           \
  -f uncropped-input.pdf

However, this may not work reliably for all types of PDFs [1]. In those cases you should alternatively try these commands:

gswin32c.exe                 ^
  -o cropped.pdf             ^
  -sDEVICE=pdfwrite          ^
  -dDEVICEWIDTHPOINTS=595    ^
  -dDEVICEHEIGHTPOINTS=842   ^
  -dFIXEDMEDIA               ^
  -c "24 72 translate"       ^
  -c " 0 0 535 722 rectclip" ^
  -f uncropped-input.pdf

or

gs                           \
  -o cropped.pdf             \
  -sDEVICE=pdfwrite          \
  -dDEVICEWIDTHPOINTS=595    \
  -dDEVICEHEIGHTPOINTS=842   \
  -dFIXEDMEDIA               \
  -c "24 72 translate"       \
  -c " 0 0 535 722 rectclip" \
  -f uncropped-input.pdf

[^] : To be more specific: it will not work for PDFs which come along with their own /CropBox already defined to specific values. A dirty hack around that is to change the string /CropBox for all pages where it is desired to /cROPBoX (or similar case-changing) with a text editor prior to running the above GS command. The case-change effectively "disarms" the cropbox setting (without changing any PDF object offsets invalidating the existing xref table) so it is no longer considered by PDF renderers.

Upvotes: 82

Related Questions