首页 文章

如何将两个postscript文件合并在一起?

提问于
浏览
7

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

以前有人这样做过吗?那里有没有图书馆(商业或开源)?我不介意C,C#甚至Java库 .

Edited 这些是大型的postscript文件(超过200 Mb),其目的仅用于彩色打印(不适用于在线查看) .

Conclusion

  • ps2write不是答案,因为它不支持DSC .

  • pswrite作为读者pipitas正确指出产生L1输出 . 这不是解决方案 .

  • 使用pdfwrite是可行的 . 在此选项中,我们将两个ps转换为PDF,然后将合并的PDF转换为ps . 此解决方案可能存在问题,因为在转换过程中可能会丢失一些信息 . 除了额外的转换步骤,还需要额外的资源和时间 .

  • 如果我们不需要查看输出文件,将两个postscript文件连接在一起,插入文件之间的以下行"false 0 startjob pop"也是一种解决方案 . (另见this link

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

6 回答

  • 1

    下面是一个示例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
    

    Edit: 我的第一张照片错误地假设了PDF输入文件 . 它当然也适用于PostScript(甚至是PS / PDF的混合)......输出也可能是PS .

  • 1

    当然,您也可以将各种输入文件(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
    

    您应该说明哪个应用程序创建了PostScripts,以及使用了哪种设置 . 只有这样你才能期待更具体的建议 . 你的PostScripts可能会f.e.包括高分辨率图片(例如1200dpi),而您的打印设备可能只能600dpi . 在这种情况下,下采样到600dpi将使文件相当小,而不必强加质量罚款 .

  • 13

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

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

  • 3

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

    © Angus J. C. 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;
    }
    
  • 1

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

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

    有谁有类似的问题?

  • 2

    正如OP在问题的结论中提到的那样,用the line连接文件

    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文件之外的所有文件 . 更多细节可以在here找到 .

相关问题