4

通过查看 Kurt Pfeifle 的一些答案,我创建了一个将两个 PDF 并排合并到一起的脚本。

但我的问题是代码不灵活。我的意思是,如果一个 PDF 更大或具有另一个 PDF 的另一个分辨率,则输出 PDF(并排 PDF)将是错误的。

说明它看起来像这样:

Input file: a.pdf
+--------+ 
|        |
|  a     |
|        |
+--------+

Input file: b.pdf
+--------+ 
|        |
|  b     |
|        |
+--------+

Desired output file: compare.pdf
+--------+--------+ 
|        |        |
|   a    |  b     |
|        |        |
+--------+--------+

所以我需要确保在合并它们之前,PDF 都具有相同的常规 A4 尺寸 PDF 和分辨率?我已经尝试了很多代码和脚本,但无法弄清楚这一点。我怎样才能做到这一点?该脚本需要是防弹的,以便可以使用和比较任何 PDF。即使他们没有相同的大小。

我的脚本现在看起来像这样,并且适用于一些具有相同大小和分辨率的 PDF:

gswin64c.exe                        ^
          -o c.pdf                  ^
          -sDEVICE=pdfwrite         ^
          -g11690x8270              ^
          -dFIXEDMEDIA              ^
          -dPDFSETTINGS=/prepress   ^
          -r300                     ^
          -c "<</PageOffset [0 0]>>setpagedevice" ^
          -f a.pdf

这将创建c.pdf,如下所示:

c.pdf
+--------+--------+ 
|        |        |
|   a    | (empty)|
|        |        |
+--------+--------+

下一个命令:

gswin64c.exe                       ^
          -o left-side-outputs.pdf ^
          -sDEVICE=pdfwrite        ^
          -g11690x8270             ^
          -dPDFSETTINGS=/prepress  ^
          -c "<</PageOffset [0 0]>>setpagedevice" ^
          -f b.pdf

这将创建left-side-outputs.pdf,如下所示:

left-side-outputs.pdf
+--------+--------+ 
|        |        |
|   b    | (empty)|
|        |        |
+--------+--------+

下一个命令:

gswin64c.exe                        ^
          -o right-side-outputs.pdf ^
          -sDEVICE=pdfwrite         ^
          -g11690x8270              ^
          -dPDFSETTINGS=/prepress   ^
          -c "<</PageOffset [596 0]>>setpagedevice" ^
          -f c.pdf

这将创建right-side-outputs.pdf,如下所示:

right-side-outputs.pdf
+--------+--------+ 
|        |        |
|(empty) |  b     |
|        |        |
+--------+--------+

最后一个命令:

pdftk left-side-outputs.pdf multistamp right-side-outputs.pdf output compare.pdf

这将创建最终结果compare.pdf

Desired output file: compare.pdf
+--------+--------+ 
|        |        |
|   a    |  b     |
|        |        |
+--------+--------+

我希望那里的一些大师可以帮助我弄清楚如何处理具有不同页面大小的 PDF 输入文件。

4

2 回答 2

3

对于你的问题...

所以我需要确保在合并它们之前,PDF 都具有相同的常规 A4 尺寸 PDF 和分辨率?

...答案是“是的,关于页面大小 - 没有关于分辨率(没关系)。”

使用 Ghostscript 缩放 PDF 页面(一)

将混合大小 PDF 的所有页面缩放为全 A4 的命令如下:

 gswin64c.exe           ^
     -o all-a4.pdf      ^
     -sDEVICE=pdfwrite  ^
     -g5950x8420        ^
     -dPDFFitPage       ^
     -f input.pdf

这同样可以缩放媒体大小和内容(使用 GS v9.10 测试)。

该参数-dPDFFitPage将始终保持纵横比。它将自动旋转内容以使其最适合。它不允许“拉伸”或页面仅向一个方向。然而,这可以通过下一种方法来实现。


[更新

我认为关于这种方法的一点我确实理解得不够清楚。

事情是这样的:如果输入文件中媒体的纵横比与目标媒体的纵横比不同,则-dPDFFitPage不会完全覆盖目标媒体。

假设您的输入媒体使用方形页面大小,500x500点数。如果您使用 A4 ( -g5950x8420) 的目标大小来处理它,那么-dPDFFitPage将保持正方形纵横比并产生-g5950x5950仅的输出大小。

但是您也不能省略-dPDFFitPage- 否则您不会400x400缩放原始内容,而只会放置在较大的595x842页面上,放置在左下角。

更新结束。]


使用 Ghostscript 缩放 PDF 页面 (2)

将所有 PDF 页面内容缩放到各自尺寸的 50% 的命令如下:

 gswin64c.exe                                      ^
     -o 50pc.pdf                                   ^
     -sDEVICE=pdfwrite                             ^
     -c "<</Install {.5 .5 scale}>> setpagedevice" ^
     -f input.pdf

但是,这不会同时缩放媒体框

如果您知道PDF 文件中的所有页面大小相同,则可以使用它来将 A3 PDF 缩放为 A4:

 gswin64c.exe                                      ^
     -o A4-50pc.pdf                                ^
     -g5950x8420                                   ^
     -sDEVICE=pdfwrite                             ^
     -c "<</Install {.5 .5 scale} /AutoRotatePages /None>> setpagedevice" ^
     -f A3.pdf

但是,我的答案中的第一个命令当然也可以,而且使用起来更简单!

对于A5 -> A4A4 -> A3,请使用:

                    {1.415 1.415 scale}

对于A3 -> A4A4 -> A5

                    { .707  .707 scale}

但是现在它变得更有趣了,因为您也可以“拉伸”内容!要水平缩放到 75% 并垂直缩放到 66%,请使用

     -c "<</Install {.75 .666 scale}>> setpagedevice"

对于LetterA4之间的一种“液体”缩放,您可以使用这些:

  • A4 -> 字母:{1.028571 .940617 scale}
  • 字母 -> A4:{ .972222 1.063131 scale}

对于以上所有内容,您可以给出一个-gNNNNxMMMM值(确定输出 PDF 的固定页面大小——pdfwrite设备默认内部分辨率为 720 ppi 的像素尺寸,即 1 PostScript 点 10 像素...) -

如果您不提供-gNNNNxMMMM值,则使用原始页面大小(即使它们是混合值),但它们的内容将使用您指定的缩放因子绘制在这些页面上。

我现在不知道的是:一种“液体缩放”混合尺寸 PDF 的每个单独页面的方法,包括媒体尺寸一次......

基于 A4 比较 all-Letter 和 all-A5 PDF 文件:

假设您现在想将全字母大小的 PDF 与全 A5 的 PDF 进行比较,并且您想先将两者都缩放到 A4,您需要执行以下操作:

A4 的“液体”比例字母:

 gswin64c.exe                                      ^
     -o a4-1.pdf                                   ^
     -sDEVICE=pdfwrite                             ^
     -g5950x8420                                   ^
     -c "<</Install{.972222 1.063131 scale}>>setpagedevice" ^
     -f letter.pdf

'固定' - 比例 A5 到 A4:

 gswin64c.exe                                      ^
     -o a4-2.pdf                                   ^
     -sDEVICE=pdfwrite                             ^
     -g5950x8420                                   ^
     -c "<</Install{1.415 1.415 scale}>>setpagedevice" ^
     -f a5.pdf

或者,或者:

 gswin64c.exe          ^
     -o a4-2.pdf       ^
     -sDEVICE=pdfwrite ^
     -g5950x8420       ^
     -dPDFFitPage      ^
     -f a5.pdf

现在比较您的两个 A4 PDF 文件....

优化您的比较工作流程

您还可以保存问题中概述的工作流程的一个步骤。这是一个更好的方法。

第一步:准备左侧(和以前一样)

假设你有 A4 输入,最终输出应该是 A3:

 gswin64c.exe                   ^
      -o left-sides.pdf         ^
      -sDEVICE=pdfwrite         ^
      -g11900x8420              ^
      -c "<</PageOffset [0 0]>>setpagedevice" ^
      -f a.pdf

这将创建:

left-sides.pdf
+--------+--------+   ^
|        |        |   |
|        |        |   |
|  a     |(empty) |  595 pt == 5950 pixels
|        |        |   |
|        |        |   |
+--------+--------+   v

<-----1190 pt----->
   == 11900 pixels

第二步:准备右侧(一气呵成)

 gswin64c.exe                   ^
      -o right-sides.pdf        ^
      -sDEVICE=pdfwrite         ^
      -g11900x8420              ^
      -c "<</PageOffset [595 0]>>setpagedevice" ^
      -f b.pdf

这将创建:

right-side.pdf
+--------+--------+   ^
|        |        |   |
|        |        |   |
|(empty) |  b     |  595 pt == 5950 pixels
|        |        |   |
|        |        |   |
+--------+--------+   v

<-----1190 pt----->
   == 11900 pixels

第三步:覆盖两个文件pdftk

pdftk right-sides.pdf multistamp left-sides.pdf output compare.pdf

或者

pdftk left-sides.pdf multistamp right-sides.pdf output compare2.pdf

这将创建:

compare.pdf
+--------+--------+   ^
|        |        |   |
|        |        |   |
|  a     |  b     |  595 pt == 5950 pixels
|        |        |   |
|        |        |   |
+--------+--------+   v

<-----1190 pt----->
   == 11900 pixels

关于裁剪/修剪/艺术/出血框的更新

还有一件事。

有时上述命令可能“似乎”不起作用。原因是,PDF 在内部不仅使用天真的假设的“页面大小”,而且使用更复杂的设置(我们通常认为的“页面大小”) ,MediaBox以及TrimBox、和. 有关这些框的确切描述,请参见此处...BleedBoxArtBoxCropBox

要测试所有这些框的值的 PDF 文件(输入以及结果或中间结果),请使用以下pdfinfo命令:

pdfinfo -f 1 -l 5 -box a.pdf
pdfinfo -f 1 -l 5 -box b.pdf
pdfinfo -f 1 -l 5 -box right-sides.pdf
pdfinfo -f 1 -l 5 -box left-sides.pdf
pdfinfo -f 1 -l 5 -box compare.pdf

使CropBoxPDF 查看器(和打印机)仅显示(或打印) 上的那部分内容MediaBox,如果它的定义与MediaBox重新缩放任务的方式不同的话。如果它看到一个,它不会被 Ghostscript 触及。

文件可能已成功处理,但在查看器中,它仍会在页面上向您显示相同的视口。

为了“解除”这些框的效果,您应该使用一个非常粗略的技巧:将 PDF 中的这些字符串重命名为全小写名称。以下是使用sed命令行的方法(在 Windows 上可能不可用):

cat input.pdf                    \
   | sed 's#CropBox#cropbox#g'   \
   | sed 's#TrimBox#trimbox#g'   \
   | sed 's#BleedBox#bleedbox#g' \
   | sed 's#ArtBox#artbox#g'     \
> disarmed.pdf

或者,以某种方式更短,但不那么容易解析:

sed 's#CropB#cropb#g;s#TrimB#trimb#g;s#BleedB#bleedb#g;s#ArtB#artb#g' \
  in.pdf > out.pdf

由于 Ghostscript 是二进制文件格式,因此sed您可能会遇到以下错误消息:

sed:RE错误:非法字节序列

在这种情况下,请尝试不同的风格,例如 GNU sed,gsed...

于 2013-11-15T20:43:13.370 回答
1

PDF 文件不包含分辨率,因此这不是问题。我通常也不会将 -r 与 Ghostscript 一起使用,它所做的只是指定无法“按原样”发送到 PDF 文件中的任何内容的分辨率,以便将其转换为图像。它不会影响该内容的大小或位置。

您不应该需要 /PageOffset,我认为这根本不会产生任何影响(如果输入是 PDF)。

我不会使用 /PDFSETTINGS。通过使用它,您将导入各种预设设置,除非您确信这些都是您想要的,否则最好使用默认值并翻转您想要单独更改的任何开关。

您可能非常希望输入 /AutoRotatePages=/None,否则 pdfwrite 将尝试使大部分文本向左运行以水平书写。

您将其中一个文件转换两次,您应该尽量避免这种情况,转换越多,问题的可能性就越大。

您已在所有三个 Ghostscript 输入上指定了媒体大小,但尚未在其中两个上指定 FIXEDMEDIA。对于一个可能很好,因为它是对第一个实例的重新处理(您在其中指定 FIXEDMEDIA),但是第二个实例呢?

您实际上并没有说出您遇到的问题是什么。您也没有说单个文件中出现的问题,或者仅当您使用 pdftk 将它们合并在一起时。如果没有这些信息,以及一些演示问题的示例文件,真的不可能给你更多的指导。

哦,顺便说一句,您实际上可以直接使用 Ghostscript 进行 n-up 拼版,尽管您必须比使用 pdftk 做更多的工作。稍加努力,我可能可以在一次 Ghostscript 调用中完成所有工作。

于 2013-11-15T08:35:57.380 回答