How to merge two postscript files together?

后端 未结 6 1841
春和景丽
春和景丽 2020-12-09 06:59

I am trying to merge two or more postscript files into one. I tried concatenation but it does not work as each postscript file may have different resource header.

Ha

相关标签:
6条回答
  • Of course you can also merge various input files (PS, PDF or a mix of them) into one PostScript file. I'll include a few more tweaking parameters into the next example commandline, which will increase the RAM allowance for Ghostscript by 800 Mb (provided you have a machine with that much of memory):

     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
    

    You should state which application did create your PostScripts, and with what kind of settings. Only then you can expect some more specific advice. Your PostScripts may f.e. include hi-res pictures (e.g. at 1200dpi) whereas your print device may only be capable of 600dpi. In that case downsampling to 600dpi would make the files considerably smaller without necessarily imposing quality penalties.

    0 讨论(0)
  • 2020-12-09 07:06

    GhostScript on Linux comes with a shell script called psmerge (which is installed into the /usr/bin directory). After some simple trials, it appears that this program takes into account resource definitions. It does rely on the fact that your PostScript programs strictly conform to the Adobe DSC. The contents of the merge script reproduced here with consideration to the license:

    © 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;
    }
    
    0 讨论(0)
  • 2020-12-09 07:06

    As OP mentioned in the question's conclusions, concatenating the files with the line

    false 0 startjob pop
    

    in between should do the trick. So in bash, one could write something like

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

    However, as the question also mentions this is only useful for printing (or PDF conversion), a viewer will probably fail to display all but the first ps file. Some more details can be found here.

    0 讨论(0)
  • 2020-12-09 07:10

    Here is an example Ghostscript commandline, which would convert and merge the two (or more) PostScript files into one PDF in a one go:

     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: my first shot had falsely assumed PDF input files. It works of course with PostScript as well (or even a mix of PS/PDF)... And the output may also be PS.

    0 讨论(0)
  • 2020-12-09 07:25

    FYI I've found that this does not work right in one case - if any file but the first file has links in it, they will not be correct in the final merged PDF. In particular, if say the second PDF has a link to its second page, it will end up being a link to the second page of the merged document, which is not right...

    Note that pdftk (which can be downloaded free) will get the links right.

    0 讨论(0)
  • 2020-12-09 07:26

    I've been able to successfully merge 100+ postscript files (1500+ pages) together using both %%Begin Document/ %%End Document and the false 0 startjob pop methods.

    The problem I'm having is when printing the merged file the printer pauses for 20 - 45 seconds between the merged files.

    Anyone had similar issues?

    0 讨论(0)
提交回复
热议问题