Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resizing a PDF using Ghostscript

I am trying to scale a PDF which is for example just small of A4 size up to A4.

This works fine with portrait documents. The document is scaled up correctly and then padding is added to the top.

On landscape documents padding is not added though. Therefor the document will end up being the correct height for A4 but then not wide enough, as padding is not added on the document side (as I hoped).

This is what I use to have it working for A4 portrait documents:

gs \  -sOutputFile=output.pdf \  -sDEVICE=pdfwrite \  -sPAPERSIZE=a4 \  -dCompatibilityLevel=1.4 \  -dNOPAUSE \  -dBATCH \  -dPDFFitPage \   input.pdf 
like image 645
Matt Avatar asked Sep 16 '11 14:09

Matt


People also ask

Can Ghostscript edit PDF?

This paper intends to introduce some of the ways the Ghostscript tools can be used to manipulate a PDF file, including creation of bookmarks, annotations, and setting document properties.

How do I resize a PDF scale?

Scale PDF Documents With AcrobatOpen the file in Adobe Acrobat. Select "Print" from the File menu or press "Ctrl-P" on the keyboard. Select "Size" and then select the size option that suits your needs.

Why Ghostscript is used?

Ghostscript can be used as a raster image processor (RIP) for raster computer printers—for instance, as an input filter of line printer daemon—or as the RIP engine behind PostScript and PDF viewers. It can also be used as a file format converter, such as PostScript to PDF converter.


2 Answers

You should add the -dFIXEDMEDIA switch:

gs \  -o output.pdf \  -sDEVICE=pdfwrite \  -sPAPERSIZE=a4 \  -dFIXEDMEDIA \  -dPDFFitPage \  -dCompatibilityLevel=1.4 \   input.pdf 

-dFIXEDMEDIA is always required if you need to force a specific paper/page/media size and ignore the paper/page/media size specified in the document. Because PDF always has a paper/page/media size defined (PostScript might have, or might not have...).

(My -o ... is shorter and saves one from adding -dBATCH -dNOPAUSE -- but works only for more recent versions of Ghostscript.)

like image 110
Kurt Pfeifle Avatar answered Sep 26 '22 20:09

Kurt Pfeifle


First, thanks for everyone that posted here.

I have this little script called pdfScale which absorbed parts of the answers posted here. So I decided to post back my 2 cents. I am using a bit of a mix of Kurt's and Tim's answers. More similar to Tim's though. I have played with this for a few days and here is my partial conclusion on the methods posted here:

Set Paper Size by Name with -sPAPERSIZE

  • Easy to just pass the paper name (Eg. a4)
  • May not produce 100% accurate points size
  • May Flip Landscape <> Portrait

Set paper size in PS-points -dDEVICEWIDTHPOINTS, -dDEVICEHEIGHTPOINTS

  • Makes sure you get the size you want in points
  • You can Flip WIDTH <> HEIGHT yourself
  • You need to know the sizes in Points
  • Not so easy to script around it, as you will need the new page size in points and would also need the source's page sizes if you want to detect landscape/portrait.
  • You can set custom defined papers as well (any size you want really).
  • I was using -dDEVICEWIDTH, -dDEVICEHEIGHT instead of the longer, points version, but they both seem to do the same thing (both get points).

Because my bash script is already capable of getting source page sizes and I liked the idea to be able to set custom page sizes, I decided to focus on setting the page size in points. I had also already included the GS Paper Sizes in my script (with names and sizes). So getting that info was also easy.

Using -dFIXEDMEDIA seems to be a must on both cases, as pointed out before.

So this is how my approach went (in a scripted way)

  1. Get Source PDF page sizes (For Flip Detection)
  2. Get the target's page size in points (Eg. A4 > 595x842)
  3. Check they have the same orientation or Flip Target if necessary
  4. Run GS with points or flipped points

When I was trying to fix the auto-rotation problem, I found this other Kurt response. This is about using -dAutoRotatePages. Just copying a part of his answer here:

  • -dAutoRotatePages=/None -- retains orientation of each page;
  • -dAutoRotatePages=/All -- rotates all pages (or none) depending on a kind of "majority decision";
  • -dAutoRotatePages=/PageByPage -- auto-rotates pages individually.

My script defaults to PageByPage but that is adjustable. It worked well in my tests. Using -dAutoRotatePages also seems to reduce the need for pre-flipping the page size, even though it is not the same thing. I kept both options.

My little app was originally created to scale PDFs (without changing the page size). Then I added now the functionality to do one, the other or both. I still could not do it all in a single GS call though.

This is what I am calling for resizing, changing the variables to real values. This is for A4 Portrait size with PageByPage auto-rotation:

gs \ -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dSAFER \ -dCompatibilityLevel="1.5" -dPDFSETTINGS="/printer" \ -dColorConversionStrategy=/LeaveColorUnchanged \ -dSubsetFonts=true -dEmbedAllFonts=true \ -dDEVICEWIDTHPOINTS=595 -dDEVICEHEIGHTPOINTS=842 \ -dAutoRotatePages='/PageByPage' \ -dFIXEDMEDIA -dPDFFitPage \ -sOutputFile='../myOutputFile.pdf' \ -f '../input.pdf' 

Please note that I am also using -dFIXEDMEDIA AND -dPDFFitPage. Because this fits-to-page, the other part of my script may be handy to scale the contents inside the PDF after resizing (specially if the proportion of the PDF changed a lot). And that is one of the reasons I always run the scaling after resizing in my script (in mixed mode).

About the fraction problems when using the Paper Name, I had that happening to me before I rounded the conversions from mm/inches to points. After I started rounding them, they seem to always be the one needed. Seems weird that GS would floor those values though.

So my conclusion is that the hard part is to find a solution that works across the board on different documents with different sizes and orientations. I am still not sure I am using the proper solution. But by letting the user change the Flip Detection and GS Auto-Rotation I hope to have a solution for at least most cases.

I have also rebuilt most of the code in the process and it is pretty easy to read now. May be useful to check it if you want to automate such a task yourself. Also useful to just scale/resize PDFs as well of course:

https://github.com/tavinus/pdfScale

PS: pdfScale has its origins on this StackOverflow thread.

like image 29
Gus Neves Avatar answered Sep 26 '22 20:09

Gus Neves