Ghostscript错误使用pdfwrite将多页PS转换为多页PDF

Posted

技术标签:

【中文标题】Ghostscript错误使用pdfwrite将多页PS转换为多页PDF【英文标题】:Ghostscript error converting multi-page PS to multi-page PDF using pdfwrite 【发布时间】:2013-09-17 23:57:27 【问题描述】:

我正在使用Matlab输出一个多页的PS文件:

print(figure, '-dpsc2', fullfile(folder, [file '.ps']), '-r600', '-append')

然后使用 Matlab 调用 Ghostscript 将生成的 PS 文件转换为 PDF:

system(['"' gsPath '" -sDEVICE=pdfwrite \
 -dDEVICEWIDTHPOINTS=' num2str(int32(width*72)) ' \
 -dDEVICEHEIGHTPOINTS=' num2str(int32(height*72)) ' \
 -dPDFFitPage \
 -o "' fullfile(folder, [file '.pdf']) '" "' fullfile(folder, [file '.ps']) '"']);

这只是一种非常难以阅读的写法

gswin64c -sDEVICE=pdfwrite ^
 -dDEVICEWIDTHPOINTS=100 ^
 -dDEVICEHEIGHTPOINTS=100 ^
 -dPDFFitPage ^
 -o "C:\folder\output.pdf" "C:\folder\input.ps"

我在其中输入了设备尺寸和输入/输出路径的示例值。当我使用此代码将单个图形(一页)打印为 PDF 时,一切正常。但是,将多个图形(多页)打印到 PDF 时,Ghostscript 会抛出错误:

GPL Ghostscript 9.06 (2012-08-08)
Copyright (C) 2012 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
**** Unable to open the initial device, quitting.

现在,如果我删除 Ghostscript 命令的 -dDEVICEWIDTHPOINTS=100 -dDEVICEHEIGHTPOINTS=100 部分并再次尝试将多个图形打印到 PDF,它可以正常工作(除了页面大小与我想要的不同)。

GPL Ghostscript 9.06 (2012-08-08)
Copyright (C) 2012 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Loading NimbusSanL-Regu font from %rom%Resource/Font/NimbusSanL-Regu... 4032872 2490784 2311720 1014184 2 done.

有没有其他人遇到过类似的问题并找到了解决此问题的方法?这里的关键之一是我需要能够控制生成的 PDF 的页面大小。谢谢!

【问题讨论】:

您可能需要将反斜杠加倍。 Postscript 将反斜杠解释为转义。 如果您认为自己发现了一个错误,请在 bugs.ghostscript.com 上报告它 【参考方案1】:

下面是一个应该可以正常运行的示例。首先我们创建一个多页PS文件:

fname = 'test';
if exist([fname '.ps'], 'file'), delete([fname '.ps']); end

hfig = figure;
for i=1:10
    plot(cumsum(rand(100,1)-0.5))
    drawnow
    print(hfig, '-dpsc2', '-append', [fname '.ps'])
end
close(hfig)

接下来我们使用 Ghostscript 将其转换为 PDF,并正确裁剪图形:

gs_path = 'C:\Program Files\gs\gs9.07\bin\gswin64c.exe';
gs_opts = '-dBATCH -dNOPAUSE -q';

% ps2pdf
cmd = sprintf('"%s" %s -sDEVICE=pdfwrite -dPDFFitPage -o %s %s', ...
    gs_path, gs_opts, [fname '.pdf'], [fname '.ps']);
disp(cmd); system(cmd);

% get bbox
cmd = sprintf('"%s" %s -sDEVICE=bbox %s', ...
    gs_path, gs_opts, [fname '.pdf']);
disp(cmd); [~,out] = system(cmd);
out = textscan(out, '%s', 'Delimiter','');
bbox = regexp(out1, '^%%BoundingBox: (\d+) (\d+) (\d+) (\d+)','tokens','once');
bbox = str2double(vertcat(bbox:));
bbox = [min(bbox(:,1:2)) max(bbox(:,3:4))];

% crop to bounding box
cmd = sprintf(['"%s" %s -o %s -sDEVICE=pdfwrite' ...
    ' -dDEVICEWIDTHPOINTS=%d -dDEVICEHEIGHTPOINTS=%d -dFIXEDMEDIA' ...
    ' -c "<</PageOffset [-%d -%d]>> setpagedevice" -f %s'], ...
    gs_path, gs_opts, [fname '_cropped.pdf'], ...
    bbox(3)-bbox(1), bbox(4)-bbox(2), bbox(1), bbox(2), [fname '.pdf']);
disp(cmd); system(cmd);

【讨论】:

以上是关于Ghostscript错误使用pdfwrite将多页PS转换为多页PDF的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止 Ghostscript 和 pdfwrite 将图像分解为多个 XObject?

Ghostscript 和 PDF 字体错误

Ghostscript:“不可恢复的错误:setpagedevice 中的未定义文件名”

使用 Ghostscript 将 TIFF 转换为 PDF

Ghostscript 不生成 pdf

使用 Ghostscript 分割 PDF