如何在命令行中叠加两个Postscript文件?

7

我知道这里之前已经有类似的问题得到了解答:

然而,由于它们没有直接回答我的具体问题,所以我会尝试再次提问。

 

我想知道如何叠加两个Postscript文件:一个是标志:

...一个图形背景,另一个在其上方:

...在Linux中使用命令行方式。

 

在这里很重要的一点是,图形背景尽可能保留其原始内容。因此,如果可以以某种方式连接两个原始的后置文件内容而不改变它们(如下所示),我可能会感到最满意-但除此之外,我想知道像ghostscript这样的命令行工具如何用于此目的。

 

问题 - 徽标覆盖在PCB .ps打印输出顶部

以下是更详细的问题描述 - 我想在PCB板打印上添加徽标。我使用kicad开发PCB印刷电路板;完成后,我将各个层导出为PostScript文档。通常,我希望正面铜层"镜像";我经常尝试加载.ps输出到例如inkscape中,然后尝试在那里进行镜像操作。使用inkscape也很方便,因为可以轻松添加徽标(然后一起镜像打印和徽标)。

但是,使用inkscape处理PostScript输出是一项昂贵的操作(因为需要一段时间才能加载inkscape并执行镜像和保存操作)...虽然,主要的障碍在于:处理后,输出文件中的某些尺寸可能会稍微改变inkscape引起(而这在目标是打印少于一毫米宽的轨迹时会有很大的影响)。

 

因此,鉴于的“Plot”命令有一个镜像选项——当然,更好的方法是直接从的“Plot”命令中“镜像”层打印;输出又是一个后置文件。是这样一个(镜像)后置文件的示例。请注意,通常,“铜”部分都是黑色填充——而我基本上想在其上方放一个白色徽标。
现在,由于这个打印已经“镜像”了——如果我想在其上面添加一个徽标,那么我最好也把徽标镜像一下。所以我启动了;并且:
  • 为标志添加文本;
  • 通过文档属性设置:
    • 使文档大小与标志大小相匹配,并且
    • 文档应具有黑色背景
  • 然后将标志文本更改为白色填充;
  • 对于标志文本,执行对象/水平翻转;然后
  • 执行文件/另存为副本;
    • 选择PostScipt(*.ps)作为输出;
    • 在对话框中选择PostScript level 2,并且
    • 在导出之前选择“将文本转换为路径”。

这就是上面链接的logo.ps生成的方式(请注意,对于这种小型标志:如果没有“将文本转换为路径”,.ps文件(带有字体)可能高达20 kB;而仅使用路径则为5 kB)。

但是,一个问题是postscript实际上不支持类似于“文档背景”颜色的东西 - 显然需要自己定义填充矩形:

因此,如果您打开logo.ps,您将什么也看不到 - 因为它包含白色字母和白色背景。

查看器

如果在logo.ps中用0.5 g替换1 g行,则标志变为灰色(并且可见),并在以下情况下呈现:evincegs原始查看器和gv

view-logo.png

这是关于 tmp-Front.ps 的同样比较:

view-tmp-Front.png

值得注意的是,原始的ghostscript查看器忽略了边界框和页面方向 - 更为问题的是,如果您在净书上使用Ubuntu Gnome,则顶部和底部栏可能会裁剪ghostscript查看器窗口的一部分 - 足以使左下角的徽标不可见;并且由于“...原始的ghostscript查看器gs...没有真正的用户界面”,因此,启动时徽标被裁剪的gs窗口不能在之后设置显示它。

 

合并 .ps 文件内容以进行覆盖

通过查看以下参考资料:

据我猜测,原则上应该可以将两个postscript文件的文件内容合并; 如果合并后的文件中只有一个showpage命令,则原则上应该得到两者的叠加效果。然而,我尝试过了,但实际上我无法让它工作。

如果可能的话,我希望能够直接复制/粘贴后续文件内容(从而避免任何与文档尺寸/大小/分辨率相关的问题),然后可能使用 translate 后续命令(请参见Gnuplot中的后续编辑)来调整标志的位置。将“叠加”(合并)的 .ps 文件在 evince 中打开,每次在文本编辑器中更改 translate 参数时都会刷新文档显示——因此通过这种方式处理标志定位应该相对容易。

 

然而我也预见到一些问题:首先,图形(tmp-Front.ps)包含以下内容:
%%BoundingBox: 0 0 596 843
%%DocumentMedia: A4 595 842 0 () ()
...
0.0072 0.0072 scale
...
30085 54415 moveto
...

...而logo.ps包含:

%%BoundingBox: 0 0 31 13
...
%%DocumentMedia: 11x4mm 31 13 0 () ()
...
25.539 9.536 m(oveto) ...
...

因此,存在两个主要区别:

  • 文件的文档大小不同
  • 比例尺(或者说分辨率/坐标系)也不相同

由于我无法使文件内容串联起来,因此我真的不确定这些差异是否会影响叠加... 我当然希望它们以某种方式独立呈现;而translate只是帮助正确设置它们的相对位置 :)

 

如果我想通过连接Postscript文件内容来实现覆盖,该怎么做呢?如果这太麻烦了-我可以如何使用ghostscript(或任何其他工具)来设置覆盖层?

 

非常感谢您提前提供任何答案,
干杯!

 


供参考,这里提供了所提到的后置文件的副本(因为它们不太大):

tmp-Front.ps:

%!PS-Adobe-3.0
%%Creator: PCBNEW-PS
%%CreationDate: Thu Mar 22 09:50:52 2012
%%Title: /tmp-Front.ps
%%Pages: 1
%%PageOrder: Ascend
%%BoundingBox: 0 0 596 843
%%DocumentMedia: A4 595 842 0 () ()
%%Orientation: Landscape
%%EndComments
%%Page: 1 1
/line {
    newpath
    moveto
    lineto
    stroke
} bind def
/cir0 { newpath 0 360 arc stroke } bind def
/cir1 { newpath 0 360 arc gsave fill grestore stroke } bind def
/cir2 { newpath 0 360 arc gsave fill grestore stroke } bind def
/arc0 { newpath arc stroke } bind def
/arc1 { newpath 4 index 4 index moveto arc closepath gsave fill grestore stroke } bind def
/arc2 { newpath 4 index 4 index moveto arc closepath gsave fill grestore stroke } bind def
/poly0 { stroke } bind def
/poly1 { closepath gsave fill grestore stroke } bind def
/poly2 { closepath gsave fill grestore stroke } bind def
/rect0 { rectstroke } bind def
/rect1 { rectfill } bind def
/rect2 { rectfill } bind def
/linemode0 { 0 setlinecap 0 setlinejoin 0 setlinewidth } bind def
/linemode1 { 1 setlinecap 1 setlinejoin } bind def
/dashedline { [50 50] 0 setdash } bind def
/solidline { [] 0 setdash } bind def
gsave
0.0072 0.0072 scale
linemode1
82670 0 translate 90 rotate
60 setlinewidth
60 setlinewidth
newpath
30085 54415 moveto
30085 52585 lineto
31915 52585 lineto
31915 54415 lineto
30085 54415 lineto
poly1
newpath
87950 54930 moveto
32094 54930 lineto
32094 54474 lineto
32094 54415 lineto
32094 52525 lineto
32071 52470 lineto
32029 52428 lineto
31974 52406 lineto
31915 52406 lineto
30025 52406 lineto
29970 52429 lineto
29928 52471 lineto
29906 52526 lineto
29906 52585 lineto
29906 54475 lineto
29929 54530 lineto
29971 54572 lineto
30026 54594 lineto
30085 54594 lineto
31975 54594 lineto
32030 54571 lineto
32072 54529 lineto
32094 54474 lineto
32094 54930 lineto
28300 54930 lineto
28300 17800 lineto
87950 17800 lineto
87950 54930 lineto
poly1
100 setlinewidth
newpath
87950 54930 moveto
32094 54930 lineto
32094 54474 lineto
32094 54415 lineto
32094 52525 lineto
32071 52470 lineto
32029 52428 lineto
31974 52406 lineto
31915 52406 lineto
30025 52406 lineto
29970 52429 lineto
29928 52471 lineto
29906 52526 lineto
29906 52585 lineto
29906 54475 lineto
29929 54530 lineto
29971 54572 lineto
30026 54594 lineto
30085 54594 lineto
31975 54594 lineto
32030 54571 lineto
32072 54529 lineto
32094 54474 lineto
32094 54930 lineto
28300 54930 lineto
28300 17800 lineto
87950 17800 lineto
87950 54930 lineto
poly0
1 1 1 setrgbcolor
60 setlinewidth
31000 53500 170 cir1
0 0 0 setrgbcolor
showpage
grestore
%%EOF

logo.ps:

%!PS-Adobe-3.0
%%Creator: cairo 1.10.2 (http://cairographics.org)
%%CreationDate: Thu Mar 22 10:07:46 2012
%%Pages: 1
%%BoundingBox: 0 0 31 13
%%DocumentData: Clean7Bit
%%LanguageLevel: 2
%%DocumentMedia: 11x4mm 31 13 0 () ()
%%EndComments
%%BeginProlog
/languagelevel where
{ pop languagelevel } { 1 } ifelse
2 lt { /Helvetica findfont 12 scalefont setfont 50 500 moveto
  (This print job requires a PostScript Language Level 2 printer.) show
  showpage quit } if
/q { gsave } bind def
/Q { grestore } bind def
/cm { 6 array astore concat } bind def
/w { setlinewidth } bind def
/J { setlinecap } bind def
/j { setlinejoin } bind def
/M { setmiterlimit } bind def
/d { setdash } bind def
/m { moveto } bind def
/l { lineto } bind def
/c { curveto } bind def
/h { closepath } bind def
/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto
      0 exch rlineto 0 rlineto closepath } bind def
/S { stroke } bind def
/f { fill } bind def
/f* { eofill } bind def
/n { newpath } bind def
/W { clip } bind def
/W* { eoclip } bind def
/BT { } bind def
/ET { } bind def
/pdfmark where { pop globaldict /?pdfmark /exec load put }
    { globaldict begin /?pdfmark /pop load def /pdfmark
    /cleartomark load def end } ifelse
/BDC { mark 3 1 roll /BDC pdfmark } bind def
/EMC { mark /EMC pdfmark } bind def
/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def
/Tj { show currentpoint cairo_store_point } bind def
/TJ {
  {
    dup
    type /stringtype eq
    { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse
  } forall
  currentpoint cairo_store_point
} bind def
/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore
    cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def
/Tf { pop /cairo_font exch def /cairo_font_matrix where
      { pop cairo_selectfont } if } bind def
/Td { matrix translate cairo_font_matrix matrix concatmatrix dup
      /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point
      /cairo_font where { pop cairo_selectfont } if } bind def
/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def
      cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def
/g { setgray } bind def
/rg { setrgbcolor } bind def
/d1 { setcachedevice } bind def
%%EndProlog
%%Page: 1 1
%%BeginPageSetup
%%PageMedia: 11x4mm
%%PageBoundingBox: 0 0 31 13
%%EndPageSetup
q 0 0 31 13 rectclip q
1 g
25.539 9.536 m 25.539 7.567 l 27.227 7.567 l 27.227 3.817 l 27.227 
3.055 27.211 2.606 27.18 2.473 c 27.152 2.348 27.078 2.243 26.961 2.161 
c 26.848 2.087 26.707 2.052 26.539 2.052 c 26.324 2.052 25.992 2.13 
25.555 2.286 c 25.336 0.364 l 25.922 0.118 26.574 -0.011 27.289 -0.011 
c 27.738 -0.011 28.145 0.063 28.508 0.208 c 28.863 0.36 29.125 0.559 
29.289 0.802 c 29.457 1.04 29.574 1.364 29.633 1.77 c 29.688 2.048 
29.711 2.63 29.711 3.505 c 29.711 7.567 l 30.852 7.567 l 30.852 9.536 l 
29.711 9.536 l 29.711 11.395 l 27.227 12.833 l 27.227 9.536 l h
18.535 3.177 m 16.082 2.77 l 16.395 1.864 16.898 1.169 17.582 0.692 c 
18.262 0.223 19.117 -0.011 20.145 -0.011 c 21.77 -0.011 22.969 0.52 
23.738 1.583 c 24.355 2.434 24.66 3.509 24.66 4.802 c 24.66 6.352 
24.262 7.567 23.457 8.442 c 22.648 9.313 21.621 9.755 20.379 9.755 c 
18.996 9.755 17.902 9.294 17.098 8.38 c 16.297 7.462 15.914 6.055 
15.941 4.161 c 22.129 4.161 l 22.121 3.43 21.926 2.86 21.551 2.458 c 
21.168 2.052 20.688 1.848 20.113 1.848 c 19.73 1.848 19.406 1.95 19.145 
2.161 c 18.875 2.368 18.672 2.708 18.535 3.177 c h
18.395 5.677 m 18.418 6.391 18.605 6.934 18.957 7.302 c 19.312 7.673 
19.742 7.864 20.238 7.864 c 20.781 7.864 21.227 7.665 21.566 7.27 c 
21.922 6.884 22.098 6.352 22.098 5.677 c h
15.02 2.864 m 12.535 3.255 l 12.434 2.774 12.219 2.407 11.895 2.161 c 
11.574 1.911 11.125 1.786 10.551 1.786 c 9.906 1.786 9.422 1.899 9.098 
2.13 c 8.891 2.294 8.785 2.512 8.785 2.786 c 8.785 2.97 8.844 3.13 
8.957 3.255 c 9.082 3.368 9.359 3.477 9.785 3.583 c 11.777 4.016 13.039 
4.419 13.566 4.786 c 14.309 5.282 14.676 5.989 14.676 6.895 c 14.676 
7.696 14.359 8.372 13.723 8.927 c 13.078 9.477 12.09 9.755 10.754 9.755 
c 9.477 9.755 8.527 9.544 7.91 9.13 c 7.289 8.712 6.855 8.095 6.613 
7.286 c 8.941 6.848 l 9.047 7.212 9.242 7.489 9.52 7.677 c 9.793 7.872 
10.188 7.973 10.707 7.973 c 11.355 7.973 11.82 7.884 12.098 7.708 c 
12.285 7.571 12.379 7.403 12.379 7.208 c 12.379 7.028 12.297 6.876 
12.129 6.755 c 11.914 6.587 11.145 6.352 9.832 6.052 c 8.523 5.759 
7.598 5.391 7.066 4.958 c 6.559 4.52 6.301 3.907 6.301 3.13 c 6.301 
2.274 6.664 1.532 7.379 0.911 c 8.09 0.294 9.148 -0.011 10.551 -0.011 c 
11.824 -0.011 12.828 0.247 13.566 0.77 c 14.309 1.29 14.793 1.989 15.02 
2.864 c h
0.066 9.536 m 0.066 7.567 l 1.754 7.567 l 1.754 3.817 l 1.754 3.055 
1.738 2.606 1.707 2.473 c 1.68 2.348 1.605 2.243 1.488 2.161 c 1.375 
2.087 1.234 2.052 1.066 2.052 c 0.852 2.052 0.52 2.13 0.082 2.286 c 
-0.137 0.364 l 0.449 0.118 1.102 -0.011 1.816 -0.011 c 2.266 -0.011 
2.672 0.063 3.035 0.208 c 3.391 0.36 3.652 0.559 3.816 0.802 c 3.984 
1.04 4.102 1.364 4.16 1.77 c 4.215 2.048 4.238 2.63 4.238 3.505 c 4.238 
7.567 l 5.379 7.567 l 5.379 9.536 l 4.238 9.536 l 4.238 11.395 l 1.754 
12.833 l 1.754 9.536 l h
0.066 9.536 m f
Q Q
showpage
%%Trailer
%%EOF

编辑:关于luser droog的回答;如果我按照evince中所写的方式打开combo.ps,会出现以下情况:

$ evince combo.ps
invalidfileaccess -9

这可能与#414002 - gs -dSAFER: /invalidfileaccess with "run" operator - Debian Bug report logs有关... 如果我尝试在开头添加PostScript头"%!",我会得到:
$ nano combo.ps # added %! at start
$ evince combo.ps
undefined -21
undefined -21

我也尝试运行ps2ps - 这是输出结果:

$ ps2ps combo.ps comboB.ps
Error: /undefined in --load--
Operand stack:
   Oldshowpage
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push   1910   1   3   %oparray_pop   1909   1   3   %oparray_pop   1893   1   3   %oparray_pop   1787   1   3   %oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--
Dictionary stack:
   --dict:1159/1684(ro)(G)--   --dict:0/20(G)--   --dict:77/200(L)--
Current allocation mode is local
Current file position is 30
GPL Ghostscript 9.02: Unrecoverable error, exit code 1
3个回答

2
为了“合并”这两个文件,您需要禁用“showpage”操作符,否则这两个文件将分别发出它们的页面。但是,您需要保留原始定义,以便发出最终文档。类似这样:
/Oldshowpage showpage load def
/showpage {} def

...
file1
...
...
file2
...
Oldshowpage

如果您将重定义保存在一个文件中,并将最终执行保存在另一个文件中,那么您可以使用cat 'prolog.ps file1.ps file2.ps epilog.ps'命令。

您的两个文件都不执行媒体请求(您可以忽略%%行,它们只是注释)。

然而,正如您所说,您不希望缩放和变换在作业之间保持。因此,您需要保存和恢复图形状态。所以,在这种情况下,您还需要一个“中间”文件。

因此,prolog.ps包含:

/Oldshowpage showpage load def
/showpage {} def
gsave

middle.ps包含以下内容:

grestore

epilog.ps中包含了

Oldshowpage

将这5个文件合并起来,应该就可以正常工作。对我来说它做了一些有意义的事情,但我应该提到你的“logo.ps”在使用Ghostscript和Adobe Distiller时会产生一个空白页面。

嗨@KenS - 非常感谢您的回答!我已经编辑了它并添加了代码格式,希望这没问题(_我还没有足够的声望立即进行编辑,但我希望管理员会接受它_)。关于logo.ps是一个空白页面 - 这是因为它是白色背景上的白色图形:上面提到inkscape不会将黑色背景导出到后置输出。我尝试做:cat prolog.ps tmp-Front.ps middle.ps logo.ps epilog.ps > out.ps - 在这种情况下,只有tmp-Front.ps图形在out.ps中可见... [继续] - sdaau
然而,如果我以不同的顺序输入文件参数,即:cat prolog.ps logo.ps middle.ps tmp-Front.ps epilog.ps > out.ps - 那么只有 logo.psout.ps 中可见!(顺便说一下,在 logo.ps 文件中,在 %%EndPageSetup 之后的 1 g 行可以更改为 0.5 g;然后标志变成灰色/可见)...因此,在 prolog/middle/epilog 中必须做些其他事情...再次感谢 - 干杯! - sdaau
1
我尝试了另一种排序方式,对我来说效果非常好。至少和第一个排序一样好。标志的缩放和定位不正确,但这是可以预料的。 - KenS
谢谢你的留言,@KenS - 我想问一下,你用什么应用程序查看最终的PostScript文件?是evince还是其他什么?谢谢,祝好! - sdaau
1
使用Microsoft Visual Studio 2008查看PostScript程序,使用Ghostscript进行渲染。我应该提一下,我是Artifex Inc的员工,致力于开发Ghostscript。 - KenS
显示剩余2条评论

2
一个类似于KenS的方法是将"composition(组合)"代码放在一个单独的文件中,并使用run运算符调用组件文件。这与前一种方法的效果相同,只是少了一点shell工作。唯一的限制是-dSAFER选项(大多数Distiller安装中默认开启)会禁用run运算符。

combo.ps:

/Oldshowpage /showpage load def
/showpage {} def
gsave
    (tmp-Front.ps) run
grestore
    %additional scaling and translation to place the graphic?
    (logo.ps) run
Oldshowpage

1
现在,ps2ps应该很高兴了。但是看起来evince甚至没有定义“run”操作符。但是你可以原谅它,因为它主要是一个文档查看器。“combo.ps”对于“文档”的任何有用定义都不是一个“文档”。 - luser droog
1
你可以使用psinc来“预处理”程序并内联run。结果应该与cat的结果相同。 - luser droog
首先,非常感谢@luserdroog提供的“evince”注意事项 - 在这种情况下,它不支持“run”运算符,这对我们很有帮助! - sdaau
在查找了The Kemp Project: xfig cannot import eps files之后,我找到了OpenSuse Bug 608071Bug 691339 – Insecure gs initialization,其中提到了-P开关,man gs说它的作用是:“_使Ghostscript首先在当前目录中查找库文件._” - sdaau
2
最后,指出了一个可能是问题的“包含目录” - 所以我终于可以确认,虽然“直接”的ps2ps会崩溃 - 手动指定当前目录作为包含目录,例如:“ps2ps -I. combo.ps comboB.ps”;或者使用-P开关,例如:“ps2ps -P combo.ps comboB.ps”,将使进程顺利进行。请注意,输出的comboB.ps将被压缩(Ascii85/LZW);在evincegsgv中打开时看起来都一样 - 但是它是纵向旋转的(而应该是横向的,如tmp-Front.ps)。 - sdaau
显示剩余4条评论

1

好的,这是对我的有效方法,感谢@luserdroog的答案,使用未更改的文件,并且在evince中“直接”使用。

首先,在一个目录中获取tmp-Front.pslogo.ps 和 @luserdroog 的combo.ps(下面进行修改)。第一个问题是,如果evince遇到%%EOF,它将停止解析接下来的任何内容。因此,我们首先要摆脱tmp-Front.pslogo.ps中的那些指令:

sed -i 's/%%EOF/% %EOF/' logo.ps
sed -i 's/%%EOF/% %EOF/' tmp-Front.ps

其次,如果 evince 在文档开头没有遇到 %%Orientation 等指示,则不会将文档显示为横向(如原始的 tmp-Front.ps),因此我们应该从 tmp-Front.ps 中提取这些指示,并将它们添加到 combo.ps 的开头,并将所有内容保存为新文件 combopg.ps
cat <(echo '%!') <(grep '%%Pages\|%%PageOrder\|%%BoundingBox\|%%DocumentMedia\|%%Orientation' tmp-Front.ps) <(echo) combo.ps > combopg.ps

这里我使用以下修改版的combo.ps

/Oldshowpage /showpage load def
/showpage {} def
gsave
    (tmp-Front.ps) run
grestore
    %additional scaling and translation to place the graphic?
    1 1 scale
    300 300 translate
    0 0 moveto

    (logo.ps) run
Oldshowpage

最后,由于evince不认识run指令,我使用这个psinc的修改版psinc.pl来“包含”文件的内容:
cat combopg.ps | perl ./psinc.pl > combopgout.ps

 

现在,你终于可以在evince中打开combopgout.ps - 同时在文本编辑器中查找300 300 translate这一行;在文本编辑器中编辑这些参数并保存文件将导致evince重新加载.ps文件并显示最新位置 - 默认情况下会是这样的:

combopgout.ps.png

(请注意,徽标已根据横向方向旋转)

 

好的,我想这解决了 - 感谢你们的回答!!


很高兴看到最终的解决方案。还有图片!我认为这个问题将来对其他人非常有用。干得好! - luser droog
我当然希望如此 - 感谢您,@luserdroog!(不用担心意外的评论复制;版主已经处理了)...干杯! - sdaau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接