7

我正在尝试将两个或多个 postscript 文件合并为一个。我尝试了连接,但它不起作用,因为每个 postscript 文件可能有不同的资源头。

以前有人做过吗?那里有任何图书馆(商业或开源)吗?我不介意 C++、C# 甚至 Java 库。

已编辑 这些是大型 postscript 文件(超过 200 Mb),它们的目的仅用于彩色打印(不用于在线查看)。

结论

  1. ps2write 不是答案,因为它不支持 DSC。
  2. pswrite 正如读者 pipitas 正确指出的那样会产生 L1 输出。这不是解决方案。
  3. 使用 pdfwrite 是可行的。在此选项中,我们将两个 ps 转换为 PDF,然后将合并的 PDF 转换为 ps。此解决方案可能存在问题,因为在转换过程中可能会丢失一些信息。除了额外的转换步骤需要额外的资源和时间。
  4. 如果我们不需要查看输出文件,将两个 postscript 文件连接在一起,并在文件之间插入以下行“false 0 startjob pop”也是一种解决方案。(另请参阅此链接

总之,合并两个 postscript 文件的临时解决方案是选项 3 或 4。

4

6 回答 6

13

这是一个 Ghostscript 命令行示例,它可以一次性将两个(或多个)PostScript 文件转换并合并为一个 PDF:

 gswin32c.exe ^
   -o c:/path/to/output.pdf ^
   -sDEVICE=pdfwrite ^
   -dPDFSettings=/Screen ^
   [...more desired parameters (optional)...] ^
   /path/to/first.ps ^
   /path/to/second.ps ^
   /path/to/third.pdf

编辑:我的第一枪错误地假设了 PDF 输入文件。它当然也适用于 PostScript(甚至是 PS/PDF 的混合)......而且输出也可能是 PS。

于 2010-08-10T00:24:39.573 回答
4

当然,您也可以将各种输入文件(PS、PDF 或它们的混合)合并到一个 PostScript 文件中。我将在下一个示例命令行中包含更多调整参数,这将使 Ghostscript 的 RAM 容量增加 800 Mb(假设您有一台具有这么多内存的机器):

 gswin32c.exe ^
   -o c:/path/to/output.ps ^
   -sDEVICE=ps2write ^
  -c "800000000 setvmthreshold" ^
   [...more desired parameters (optional)...] ^
   /path/to/first.ps ^
   /path/to/second.ps ^
   /path/to/third.ps

您应该说明是哪个应用程序创建了您的 PostScript,以及使用何种设置。只有这样,您才能期待一些更具体的建议。您的 PostScript 可能包含高分辨率图片(例如 1200dpi),而您的打印设备可能仅支持 600dpi。在这种情况下,下采样到 600dpi 将使文件大大缩小,而不必施加质量损失。

于 2010-08-10T01:09:36.487 回答
2

仅供参考,我发现这在一种情况下不起作用 - 如果除第一个文件之外的任何文件中有链接,则它们在最终合并的 PDF 中将不正确。特别是,如果说第二个 PDF 有一个指向其第二页的链接,它将最终成为一个指向合并文档第二页的链接,这是不对的......

请注意,pdftk(可以免费下载)将获得正确的链接。

于 2011-03-10T18:02:14.303 回答
1

Linux 上的 GhostScript 带有一个名为psmerge(安装到/usr/bin目录中)的 shell 脚本。经过一些简单的试验后,该程序似乎考虑了资源定义。它确实依赖于您的 PostScript 程序严格符合Adob​​e DSC的事实。考虑到许可证,此处复制的合并脚本的内容:

© Angus JC Duggan 1991–1995

#!/usr/bin/perl
eval 'exec perl -S $0 "$@"'
    if $running_under_some_shell;

# psmerge: merge PostScript files produced by same application and setup
# usage: psmerge [-oout.ps] file1.ps file2.ps ...
#
# Copyright (C) Angus J. C. Duggan 1991-1995
# See file LICENSE for details.

use strict;
$^W = 1;
my $prog = ($0 =~ m,([^/\\]*)$,) ? $1 : $0;
my $outfile = undef;

usage() unless @ARGV;

while ($ARGV[0] =~ /^-/) {
   $_ = shift;
   if (/^-o(.+)/) {
      $outfile = $1;
   } elsif (/^-t(horough)?$/) {
      # This doesn't do anything, but we leave it for backward compatibility.
   } else {
      usage();
   }
}

my $gs = find_gs();
if (defined $gs)
{
   # Just invoke gs
   $outfile = '/dev/stdout' unless defined $outfile;
   exec +(qw(gs -q -dNOPAUSE -dBATCH -sDEVICE=pswrite),
      "-sOutputFile=$outfile", '-f', @ARGV);
   die "$prog: exec /usr/bin/gs failed\n";
}
else
{
   warn +("$prog: /usr/bin/gs not found; falling back to old," .
      " less functional behavior\n");
}

if (defined $outfile)
{
   if (!close(STDOUT) || !open(STDOUT, ">$outfile")) {
      print STDERR "$prog: can't open $1 for output\n";
      exit 1;
   }
}

my $page = 0;
my $first = 1;
my $nesting = 0;

my @header = ();
my $header = 1;

my @trailer = ();
my $trailer = 0;

my @pages = ();
my @body = ();

my @resources = ();
my $inresource = 0;

while (<>) {
   if (/^%%BeginFont:/ || /^%%BeginResource:/ || /^%%BeginProcSet:/) {
      $inresource = 1;
      push(@resources, $_);
   } elsif ($inresource) {
      push(@resources, $_);
      $inresource = 0 if /^%%EndFont/ || /^%%EndResource/ || /^%%EndProcSet/;
       } elsif (/^%%Page:/ && $nesting == 0) {
      $header = $trailer = 0;
      push(@pages, join("", @body)) if @body;
      $page++;
      @body = ("%%Page: ($page) $page\n");
       } elsif (/^%%Trailer/ && $nesting == 0) {
      push(@trailer, $_);
      push(@pages, join("", @body)) if @body;
      @body = ();
      $trailer = 1;
      $header = 0;
       } elsif ($header) {
      push(@trailer, $_);
      push(@pages, join("", @body)) if @body;
      @body = ();
      $trailer = 1;
      $header = 0;
       } elsif ($trailer) {
      if (/^%!/ || /%%EOF/) {
         $trailer = $first = 0;
      } elsif ($first) {
         push(@trailer, $_);
      }
       } elsif (/^%%BeginDocument/ || /^%%BeginBinary/ || /^%%BeginFile/) {
      push(@body, $_);
      $nesting++;
       } elsif (/^%%EndDocument/ || /^%%EndBinary/ || /^%%EndFile/) {
      push(@body, $_);
      $nesting--;
       }
}

print @trailer;

sub find_gs
{
   my $path = $ENV{'PATH'} || "";
   my @path = split(':', $path);
   foreach my $dir (@path)
   {
      return "$dir/gs" if -x "$dir/gs";
   }
   undef;
}

sub usage
{
   print STDERR "Usage: $prog [-oout] file...\n";
   exit 1;
}
于 2010-08-10T03:26:40.523 回答
1

我已经能够使用 %%Begin Document/ %%End Document 和 false 0 startjob pop 方法成功地将 100 多个 postscript 文件(1500 多页)合并在一起。

我遇到的问题是打印合并文件时,打印机在合并文件之间暂停 20 - 45 秒。

有人有类似的问题吗?

于 2011-01-05T21:14:01.363 回答
1

正如问题结论中提到的OP,将文件与该行连接起来

false 0 startjob pop

在两者之间应该做的伎俩。因此,在 bash 中,可以编写类似

mkdir merge
for ps in *.ps; do
    cat $ps >> merge/output.ps
    echo "false 0 startjob pop" >> merge/output.ps
done

但是,由于问题还提到这仅对打印(或 PDF 转换)有用,因此查看器可能无法显示除第一个 ps 文件之外的所有文件。可以在此处找到更多详细信息。

于 2016-04-01T07:57:52.027 回答