代码之家  ›  专栏  ›  技术社区  ›  Syd

如何合并两个postscript文件?

  •  7
  • Syd  · 技术社区  · 14 年前

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

    以前有人这样做过吗?有没有图书馆(商业的或开源的)?我不介意C++,C语言,甚至java库。

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

    1. ps2write不是它的答案
    2. 如果我们不需要查看输出文件,那么将两个postscript文件连接在一起并在文件之间插入以下行“false 0 startjob pop”也是一个解决方案(另请参见 this link )

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

    6 回复  |  直到 14 年前
        1
  •  13
  •   Kurt Pfeifle    14 年前

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

        2
  •  3
  •   Kurt Pfeifle    14 年前

    当然,您也可以将各种输入文件(PS、PDF或它们的组合)合并到一个PostScript文件中。我将在下一个示例命令行中包含更多的调整参数,这将使Ghostscript的RAM空间增加800mb(前提是您有一台内存足够大的机器):

     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,以及使用何种设置。只有这样你才能得到更具体的建议。您的Postscript可能包括高分辨率图片(例如1200dpi),而您的打印设备可能只能支持600dpi。在这种情况下,减少采样到600dpi将使文件相当小,而不必施加质量处罚。

        3
  •  2
  •   Stephen Markacs    13 年前

        4
  •  1
  •   dreamlax    14 年前

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

    安格斯J。C。达根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;
    }
    
        5
  •  1
  •   Abe    13 年前

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

    有人有类似的问题吗?

        6
  •  1
  •   Tobias Kienzler    6 年前

    正如OP在问题结论中提到的,将文件与 the line

    false 0 startjob pop
    

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

    但是,问题还提到这只对打印(或PDF转换)有用,查看器可能无法显示除第一个ps文件以外的所有ps文件。可以找到更多的细节 here .