使用 Ghostscript 调整 PDF 大小

发布于 2024-12-05 03:28:05 字数 349 浏览 0 评论 0原文

我正在尝试将 PDF 缩放为 A4 尺寸的小尺寸到 A4 尺寸。

这对于肖像文档效果很好。文档已正确缩放,然后将填充添加到顶部。

但在横向文档上不会添加填充。因此,文档最终将成为 A4 的正确高度,但宽度不够,因为文档侧未添加填充(如我希望的那样)。

我用它来处理 A4 纵向文档:

gs \
 -sOutputFile=output.pdf \
 -sDEVICE=pdfwrite \
 -sPAPERSIZE=a4 \
 -dCompatibilityLevel=1.4 \
 -dNOPAUSE \
 -dBATCH \
 -dPDFFitPage \
  input.pdf

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

游魂 2024-12-12 03:28:05

您应该添加 -dFIXEDMEDIA 开关:

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

如果您需要强制指定特定的纸张/页面/介质尺寸并忽略指定的纸张/页面/介质尺寸,则始终需要 -dFIXEDMEDIA在文件中。因为 PDF 始终定义了纸张/页面/介质尺寸(PostScript 可能有,也可能没有……)。

(我的 -o ... 更短,无需添加 -dBATCH -dNOPAUSE ——但仅适用于较新版本的 Ghostscript。)

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.)

壹場煙雨 2024-12-12 03:28:05

首先,感谢在这里发帖的所有人。

我有一个名为 pdfScale 的小脚本,它吸收了此处发布的部分答案。所以我决定退回我的 2 美分。我混合使用了库尔特和蒂姆的答案。不过与蒂姆的更相似。我已经玩了几天了,这是我对此处发布的方法的部分结论:

使用 -sPAPERSIZE 按名称设置纸张大小

  • 轻松传递纸张名称(例如 a4)
  • 可能不会产生 100% 准确的点大小
  • 可能会翻转横向 <>纵向

以 PS 磅为单位设置纸张尺寸 -dDEVICEWIDTHPOINTS-dDEVICEHEIGHTPOINTS

  • 确保获得所需的磅尺寸
  • 您可以翻转宽度 < >调整自己的高度
  • 您需要知道以磅为单位的尺寸
  • 围绕它编写脚本并不容易,因为您将需要新的页面大小(以磅为单位),并且如果您想检测横向/纵向,还需要源的页面大小。
  • 您也可以设置自定义纸张(您真正想要的任何尺寸)。
  • 我使用 -dDEVICEWIDTH-dDEVICEHEIGHT 而不是更长的积分版本,但它们似乎都做了同样的事情(都获得积分)。

因为我的 bash 脚本已经能够获取源页面大小,并且我喜欢能够设置自定义页面大小的想法,所以我决定专注于以磅为单位设置页面大小。我还已经包含了 GS 纸张尺寸 在我的脚本中(带有名称和大小)。因此获取这些信息也很容易。

正如前面指出的,在这两种情况下都必须使用 -dFIXEDMEDIA 。

这就是我的方法(以脚本方式)

  1. 获取源 PDF 页面大小(用于翻转检测)
  2. 获取目标的页面大小(例如 A4 > 595x842)
  3. 检查它们是否具有相同的大小方向或翻转目标(如有必要)
  4. 使用点或翻转点运行 GS

当我尝试修复自动旋转问题时,我发现了另一个库尔特回复
这是关于使用-dAutoRotatePages。只需在这里复制他的答案的一部分:

  • -dAutoRotatePages=/None - 保留每个页面的方向;
  • -dAutoRotatePages=/All -- 根据“多数决定”旋转所有页面(或不旋转);
  • -dAutoRotatePages=/PageByPage -- 单独自动旋转页面。

我的脚本默认为 PageByPage 但这是可以调整的。它在我的测试中效果很好。使用 -dAutoRotatePages 似乎也减少了预翻转页面大小的需要,尽管它不是同一回事。我保留了这两个选项。

我的小应用程序最初是为了缩放 PDF(不更改页面大小)而创建的。然后我现在添加了执行其中一项、另一项或两项的功能。不过,我仍然无法通过一次 GS 调用完成这一切。

这就是我所要求的调整大小,将变量更改为实际值。这是针对具有 PageByPage 自动旋转功能的 A4 纵向尺寸:

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'

请注意,我还使用 -dFIXEDMEDIA-dPDFFitPage。因为这适合页面,所以我的脚本的其他部分可以方便地在调整大小后缩放 PDF 内的内容(特别是如果 PDF 的比例发生很大变化)。这就是我总是在脚本中调整大小后运行缩放(在混合模式下)的原因之一。

关于使用纸张名称时的分数问题,在将毫米/英寸转换为点之前,我就遇到过这种情况。当我开始对它们进行四舍五入后,它们似乎总是需要的。不过,GS 会降低这些值似乎很奇怪。

所以我的结论是,困难的部分是找到一种能够全面适用于不同尺寸和方向的不同文档的解决方案。我仍然不确定我使用的是正确的解决方案。但通过让用户更改翻转检测和 GS 自动旋转,我希望至少能够为大多数情况提供解决方案。

我还在这个过程中重建了大部分代码,现在很容易阅读。如果您想自己自动执行此类任务,检查它可能会很有用。当然,对于缩放/调整 PDF 大小也很有用:

https://github.com/tavinus/pdfScale

PS:pdfScale的起源在此StackOverflow 线程

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.

雪若未夕 2024-12-12 03:28:05

似乎可以(最好)通过指定磅大小而不使用 -dPDFFitPage 来强制输出的大小。我得到的是小数点大小,这很糟糕。以下是使用按需打印服务的 A5 打印。 “真实”A5 的分辨率为 420x595 点。我发现使用 -sPAPERSIZE=a5 给出了小数点页面大小,但这可能是因为原始版本不稳定。

gs \
 -o output.pdf \
 -sDEVICE=pdfwrite \
 -dDEVICEWIDTHPOINTS=419 -dDEVICEHEIGHTPOINTS=595 \
 -dFIXEDMEDIA \
 -dCompatibilityLevel=1.4 \
  input.pdf

为了测试这一点,我发现使用 PDFshuffler 我能够导出单个页面,然后使用 pdfinfo 我能够获得这些页面的精确大小。这证实了使用设备参数确实有帮助。

It seems that the size of the output can be (best) forced by specifying the size in points and not using -dPDFFitPage. I was getting fractional point sizes, which was bad. The following is for A5 printing using a print on demand service. "Real" A5 is 420x595 points. I found that using -sPAPERSIZE=a5 gave fractional point page sizes, but that might have been because the original was wonky.

gs \
 -o output.pdf \
 -sDEVICE=pdfwrite \
 -dDEVICEWIDTHPOINTS=419 -dDEVICEHEIGHTPOINTS=595 \
 -dFIXEDMEDIA \
 -dCompatibilityLevel=1.4 \
  input.pdf

In order to test this, I found that using PDFshuffler I was able to export individual pages, then with pdfinfo I was able to get the precise size of those pages. This confirmed that using device parameters explicitly helped.

千里故人稀 2024-12-12 03:28:05

您的命令根本不进行任何缩放,它只是获取 PDF 文件并将其转换为 PDF 文件。

我建议您尝试添加 -dPDFFitPage ,它将缩放 PDF 文件中的页面以匹配当前页面大小(在本例中由 -sPAPERSIZE 指定)。

这通常适用于具有已定义纸张尺寸的打印机,因此可能不适用于没有固定页面尺寸的 pdfwrite 设备,但值得一试。

Your command doesn't do any scaling at all, it just takes a PDF file and converts it into a PDF file.

I'd suggest you try adding -dPDFFitPage which will scale the page in the PDF file to match the current page size (as specified by -sPAPERSIZE in this case).

This is usually intended to work with printers which have a defined paper size, and so may not work well with the pdfwrite device which doesn't have a fixed page size, but its worht a try.

素年丶 2024-12-12 03:28:05

遗憾的是 pstops 的功能,这是一个非常有用的软件包
缩放和合并后记页面,似乎不可用
对于 pdf 文件。有一个名为 pdftopdf 的程序,但它确实如此(据我所知
可以看到)做与 pstops 相同的事情。
您可以制作一个 ps 文件(我显然打印到文件),使用 pstops,然后
然后是 ps2pdf,但这相当笨拙。

It is a shame that the features of pstops, a very useful package for
scaling and combining pages of postscript, doesn't seem to be available
for pdfs. There is a program called pdftopdf, but it does (as far as I
can see) do the same things as pstops.
You can make a ps file (I print to file in evince), use pstops, and
then ps2pdf, but that is quite clumsy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文