Ghostscript: PDF 总页数

22
我正在使用Ghostscript库API(通过C#封装)从我的应用程序打印PDF文档。 通过使用“-dFirstPage”和“-dLastPage”参数,我可以选择要打印的页面范围,但是如何获取PDF页面的总数呢?
当PDF文档只有4页时,允许用户选择从2到10的页面间隔并不是很好。
请注意,我是通过“gsapi_init_with_args”API库调用来使用Ghostscript库的。

1
PDF必须在其元数据目录中声明其页面数。您还可以运行类似于gs -q -c“(in.pdf)(r)文件runpdfbegin pdfpagecount = quit”的命令来使Ghostscript计算页面数。 - Kurt Pfeifle
@pipitas 你好,感谢你的帮助;如果我理解正确,我需要使用“(in.pdf) (r) file runpdfbegin pdfpagecount = quit”作为GS调用的输入参数?如果是这样,“in.pdf”将是输入文件,但“(r)”呢?再次感谢。 - lorenzoff
只需使用“(r)”即可。这是Ghostscript内部宏,告诉Ghostscript读取/运行“(in.pdf)”文件... 是的,唯一的变量是in.pdf--将其替换为您的PDF的[path+]文件名。 - Kurt Pfeifle
6个回答

40

Ghostscript可以在stdout上计数和显示PDF的页面数量。其命令行为

gswin32c ^
  -q ^
  -dNODISPLAY ^
  -c "(input.pdf) (r) file runpdfbegin pdfpagecount = quit" 

这里的所有-c "..."都是一个PostScript命令行片段(使用了一些GS内部命令扩展),而input.pdf是PDF文件名(也可以是类似(c:/path/to/my.pdf)的完整路径)。

然而,更好、更快的工具来完成这种工作是使用pdfinfo(它是XPDF工具的一部分,也可在Windows上使用)。


更新:

@ebyrob想知道是否能修改我的示例命令行,以便它还可以在单个操作中显示PDF。请尝试以下内容:

gswin32c ^
  -q ^
  -c "(input.pdf) (r) file runpdfbegin pdfpagecount =" ^
  -f input.pdf

嗯,这不是单个操作--只是在一个命令行中执行的两个不同操作。


这个程序能否修改,使其在单个操作中读取元数据并显示PDF图像?(例如使用-sDEVICE=display和相关参数)同时,也能否从stdin读取文件?(即:使用gswin32 -代替文件名)仅运行-c "pdfpagecount"似乎会出现“操作不存在”的错误。包含runpdfbegin则会提示无效的文件名。 - user645280
@ebyrob:在我的命令示例中,您需要每个字符(您只能将“input.pdf”更改为不同的现有文件名或路径。您不能随意跳过任何部分... - Kurt Pfeifle
我在考虑类似这样的东西:gswin64c - -c "currentfile runpdfbegin pdfpagecount ==" < input.pdf 会有所帮助。但是,runpdfbegin使用的 setfileposition 不被 stdincurrentfile 支持。完全使用 DLL 接口在内存中工作使得从文件系统读取有些麻烦。我的“无效文件名”来自于 (%stdin) runpdfbegin 和带有 file 命令的变体。基本上,我无法成功地将 stdin 指定给 filerunpddfbegin - user645280
看起来命令行中删除了,在NT批处理脚本中使用%%。所以,我回到了setfileposition破坏runpdfbegin的地方,对于任何类似stdin或内存操作的东西。 - user645280
@KurtPfeifle 我想我找到了一个可能有用的东西:http://bugs.ghostscript.com/show_bug.cgi?id=691739 当然,我仍然需要跳过input.pdf部分...我在第一条评论中是否忘记提到我想从stdin读取? - user645280
显示剩余2条评论

4

如果使用的是ghostscript版本>9.50,遇到问题时,请增加参数--permit-file-read=input.pdf以允许读取输入文件。


2
我尝试编写了这个脚本:
gswin32c ^
  -q ^
  -c "(input.pdf) (r) file runpdfbegin pdfpagecount =" ^
  -f input.pdf

我在使用一个用C#封装的解决方案时,一直遇到错误“/undefinedfilename”。在这种情况下,请确保你的文件路径中使用的是斜杠“/”,而不是反斜杠“\”作为目录分隔符。我知道Kurt Pfeifle已经写过这个内容,但我当时只是忽略了它。


如果你想使用反斜杠,每次都必须使用两个... - Kurt Pfeifle

1

在Windows系统中:

"gs执行文件路径" -q -dNODISPLAY -dNOSAFER --permit-file-read="您的文件路径" -c "(""您的文件路径"") (r) file runpdfbegin pdfpagecount = quit"

备注:

  • 只需更改'路径到...'中的位置为您的路径,其余内容保持不变。
  • 在-c路径上,您必须使用双斜杠或类Unix的斜杠。例如: C:\\youfile.pdf (好), C:/youfile.pdf (好), C:\yourfile.pdf (不好)。

示例:

  • 路径: C:\Temp\Some Folder\myFile.pdf
  • gs路径: C:\Temp\Some Folder\gs\bin\gswin64c.exe
  • 路径-c1: C:\\Temp\\Some Folder\\myFile.pdf
  • 路径-c2: C:/Temp/Some Folder/myFile.pdf

命令:

"C:\Temp\Some Folder\gs\bin\gswin64c.exe" -q -dNODISPLAY -dNOSAFER --permit-file-read="C:\Temp\Some Folder\myFile.pdf" -c "(""C:\\Temp\\Some Folder\\myFile.pdf"") (r) file runpdfbegin pdfpagecount = quit"

"C:\Temp\Some Folder\gs\bin\gswin64c.exe" -q -dNODISPLAY -dNOSAFER --permit-file-read="C:\Temp\Some Folder\myFile.pdf" -c "(""C:/Temp/Some Folder/myFile.pdf"") (r) file runpdfbegin pdfpagecount = quit"

0
对于任何人对此无法正常工作感到非常困惑(就像我一样),实际上需要在命令行中使用一个插入符(^)字符,而不需要任何换行符。使用正斜杠(/)作为路径分隔符,文件名周围不要使用双引号(")或双双引号("")。
gswin32c -q -dNODISPLAY ^ -c "(C:/Temp/Some Input.pdf) (r) file runpdfbegin pdfpagecount = quit"

顺便说一句,这些中的任何一个 - 我的回答或其他人的回答 - 都无法与GhostScript API配合使用。它总是会返回'undefinedfilename'并且还会使API停止运行。 - undefined

0
总结一下上面的一些单独评论,为了避免在/和\\之间进行更改,显示页面总数可以设置为拖放或“发送到”的快捷方式,首先要切换到工作目录。针对Windows用户。
@echo off & cd /d "%~dp1" & "C:\path to gs\bin\gs.exe" -q --permit-file-read="%~nx1" -c "(%~nx1) (r) file runpdfbegin pdfpagecount = quit" & pause

其中gs.exe是Windows c(onsole)变体之一,gswin32c.exe或gswin64c.exe

  • cd /c“%〜dp1”将控制台切换到引用的文件驱动器路径
  • 对于“GSwin..c.exe”的完整引用路径可以安全地远程调用它
  • -q将抑制(不显示)启动消息
  • 自版本9.5+以来,建议/需要使用--permit-file-read =“文件名”
  • -c“(%〜nx1)”不需要名称.xtension的引号
  • 如果作为快捷方式运行cmd,则需要暂停以查看结果

请注意,仅在您信任的文件上使用,因为它会覆盖GS-dSAFER限制。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接