首页 > 解决方案 > Ghostscript 命令行 - 将参数传递给包含的文件

问题描述

我用 node.js 和 Ghostscript 开发 pdf 转换应用程序。我gsexec(). 我的命令定义如下所示:

let gs_cmd = `
               gs -sDEVICE=pdfwrite \
                  -dPDFX=true \
                  -dPDFACompatibilityPolicy=1 \
                  -sColorConversionStrategy=/CMYK \
                  -sProcessColorModel=DeviceCMYK \
                  -sDefaultCMYKProfile=${icc_profile_file} \
                  -dNoOutputFonts \
                  -dBATCH \
                  -dQUIET \
                  -r${DPI} \
                  -g${w}x${h} \
                  -dPDFFitPage \
                  -NumRenderingThreads=4 \
                  -o ${target_file}-conv.pdf \
                  PDFX_def.ps \
                  @trimbox.in "Trimed" \
                  ${target_file}.pdf
            `;

我的线路有问题:

@trimbox.in "Trimed" \

它告诉 Ghostscript 包含文件并将参数传递给 in。我找不到合适的方法来包含可在包含文件中使用的参数。我想将"Trimed"字符串作为$0参数传递,该参数将在trimbox.in文件中可用。我也试过有-t=Trimmed-t="Trimmed"没有效果。

来自 Ghostscript文档第 10.1 节):

@文件名

使 Ghostscript 读取文件名并将其内容视为与命令行相同。(这主要是为了绕过 DOS 对命令行长度的 128 个字符的限制。)文件中的开关或文件名可以用任意数量的空格(空格、制表符、换行符)分隔;文件大小没有限制。

-- 文件名 arg1 ...
-+ 文件名 arg1 ...

像往常一样将下一个参数作为文件名,但在运行文件之前,将所有剩余的参数(即使它们具有开关的语法形式)并在 userdict(不是 systemdict)中将名称ARGUMENTS定义为这些字符串的数组。当 Ghostscript 执行完文件后,它会退出到 shell。

如何做到这一点?

运行我的命令会导致错误:

错误:/未定义在 Trimed

标签: node.jspdfghostscript

解决方案


首先,您应该查看 Ghostscript 许可证以确保您的使用符合许可证 (AGPL v3)。请注意,这包括软件即服务应用程序。

“Trimed”不是 Ghostscript 开关,也不是输入文件的名称,所以是的,您会收到错误消息。您不能将参数“传递”给@file,因为 Ghostscript 将其视为包含一堆开关的文件。没有命令替换或类似东西。因此,@file 指定的文件中不能有 $0。

所以当你说:

@PDFX_def_trimbox.ps“修剪”\

它告诉 Ghostscript 包含文件并将参数传递给 in

恐怕你不正确。使用@file 语法时,无法向文件“传递参数”。

您还没有说出“PDFX_def_trimbox.ps”文件中的内容,我怀疑(因为 .ps)这是一个 PostScript 程序。您不能使用带有@file 语法的 PostScript 程序,因为 PostScript 程序不是一系列 Ghostscript 开关。

所以你在哪里:

-sDEVICE=pdfwrite \
-dPDFX=true\

等等,您可以将所有这些开关放入@file 指定的文件中。但是你不能在里面放任何 PostScript。

还有一些其他问题。您已指定 NumRenderingThreads=4,它什么也不做,因为 pdfwrite 设备(通常)不进行任何渲染,它尽可能将输入保留为矢量数据。所以 pdfwrite 完全忽略了这个参数。

出于类似的原因,-r 参数不太有用。在 pdfwrite 的情况下,这只会影响转换的准确性。你不应该在没有充分理由的情况下设置它。

当它应该是 =-sColorConversionStrategy=CMYK-dColorConversionStrategy=/CMYK 时,您已经设置了 -sColorConversionStrategy=/CMYK。-s 接受字符串,-d 接受数字或名称。

-g 以像素为单位设置页面的宽度和高度,这不是一个好计划,这取决于分辨率。您应该改为 -dDEVICEWIDTHPOINTS 和 -dDEVICEHEIGHTPOINTS,而不是设置分辨率。

-编辑-

-回复下面的评论-

如果您希望 PDF 文件包含 300 dpi 的图像,那么您需要创建一个大小正确的页面,以便在其上绘制时,来自图像的位图数据为 300 dpi。

例如,如果您有一个 600 像素 x 900 像素的图像,那么为了获得 300 dpi,您必须将介质尺寸设为 2 英寸 x 3 英寸,即 144 x 216 点。更改 pdfwrite 设备的分辨率根本不会影响它。设置 -g 和 -r 将改变媒体大小,但不会改变图像的分辨率,但如果您还设置 -dPDFFitPage 那么是的,它将重新调整图像以适应媒体,这改变其分辨率.....

我不知道您的原始图像是否为 300 dpi,如果是,并且 SVG 到 PDF 的转换保持这一点,那么您根本不需要弄乱媒体尺寸和分辨率,pdfwrite 设备将保持那里的一切.

至于@file 语法,你不能这样做:

-c "[ {ThisPage} << /TrimBox [$0 $1 $2 $3] >> /PUT pdfmark"

在通过@comamnd 提供的文件中,因为正如我所说,Ghostscript 对该文件内容进行的处理中没有变量替换。这不是 bash 脚本。


推荐阅读