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

时间:2010-08-09 23:24:31

标签: postscript ghostscript

我正在尝试将两个或多个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”也是一种解决方案。 (另见this link
  5. 总之,合并两个postscript文件的临时解决方案是选项3或4。

6 个答案:

答案 0 :(得分: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。

答案 1 :(得分:3)

当然,您还可以将各种输入文件(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将使文件相当小,而不必强加质量处罚。

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

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;
}

答案 4 :(得分:1)

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

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

有人有过类似的问题吗?

答案 5 :(得分:1)

正如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