1

为什么 Ghostscript pswrite 在其输出中对我的文本进行编码?考虑以下 MWE:

%!PS-Adobe-3.0 
%%Title: mwe.ps
%%Pages: 001
%%BoundingBox: 0 0 595 842
%%EndComments

%%Page: 1 1
%%PageBoundingBox: 0 0 595 842
0 0 1 setrgbcolor
0 0 595 842 rectfill
1 0 0 setrgbcolor
247 371 100 100 rectfill
/Times-Roman findfont
72 scalefont
setfont
newpath
247 300 moveto
(Chris) show
showpage

将此 MWE 保存到文件并在 GSview 中查看将显示一个带有红色方块的蓝色页面,下面是我的名字。现在使用以下命令行通过 Ghostscript 9.06 运行此文件:

"c:\Program Files\gs\gs9.06\bin\gswin64c.exe" ^
  -dSAFER -dBATCH -dNOPAUSE ^
  -sDEVICE=pswrite -sPAPERSIZE=a4 -r72 -sOutputFile=mwe_gs.ps mwe.ps

请参阅下面的 Ghostscript 输出。有人可以解释一下这里发生了什么。虽然两个 rectfill 命令仍然很明显,但我的文本 (Chris) 已被编码并且不再可区分。

请问有没有替代的后记设备可以保留我的文字?

<snip>
%%Page: 1 1
%%PageBoundingBox: 0 0 595 842
%%BeginPageSetup
GS_pswrite_2_0_1001 begin
595 842 /a4 setpagesize
/pagesave save store 197 dict begin
1 1 scale
%%EndPageSetup
gsave mark
255 0 r6
0 0 595 842 rf
255 0 r3
247 371 100 100 rf
Q q
0 0 595 0 0 842 ^ Y
255 0 r3
249 299 43 50 /5D
$C
,6CW56m1G"ZORNkWR*rB:!c2;9rlWTH="2^^[(q"h>cG<omZ2l^=qC[XbO:8_[?kji-8^"N#3q*
jhL~>
,
289 300 41 49 /0P
$C
4r?0p$m<EkK3,0>s8W-!s8W-!s8W,u]<1irI=*p=<t0>_@<)>Is8K6,aTi'$~>
,
325 300 30 33 /5I
$C
49S"pc4+Rhs8W-!s8W)oqdD:saRZq[4+k%):]~>
,
349 300 24 49 /0T
$C
4q%Ms%;PqCs8W-!s8W%1_qkn/K?*sYFSGd:5Q~>
,
377 299 23 34 /5M
$C
-TQR7$&O'!K+D:XribR9;$mr4#sqUi.T@,dX=Y&Llg+F`d^HC#%$"]~>
,
cleartomark end end pagesave restore
 showpage
%%PageTrailer
%%Trailer
%%Pages: 1
%%EOF

注意:这可能看起来很奇怪,但我正在探索使用 Ghostscript 来“清理”来自 Matlab 应用程序的 postscript 输出的想法。

4

3 回答 3

6

“文本”已转换为图像,而不是矢量路径。这是 pswrite 设备的严重限制,也是不推荐使用的原因之一,您应该改用 ps2write 设备。仍然包含 pswrite 设备的唯一原因是 epswrite 使用它(这就是 pswrite 和 epswrite 输出看起来相同的原因)。在某个时候会有一个 eps2write 设备,并且 pswrite 将被分箱。

ps2write 输出默认是压缩的。如果您想要未压缩的输出,请在命令行上使用 -dCompressPages=false 开关。

如果您想要的只是文本的位置,您可以考虑使用 txtwrite 设备。默认实现会创建输入的纯文本表示,但您可以让它输出伪造的 XML,而不是包含文本来源等内容。

于 2013-02-14T08:34:08.580 回答
1

下面是一个简单的示例,显示操作符被重新定义以显示有关节目的位置信息,同时执行标准的节目操作。使用 ghostscript,您可以运行多个文件,因此头文件将是另一个文件的前缀,这会改变标准行为。

重新定义的节目可能包括字体名称和大小。数据可能已写入磁盘文件,而不是转储到控制台。也可以重新定义任何其他运算符,例如 rectfill、fill、stroke... 因为原来的运算符也被调用,所以您可以使用 pdfwrite 设备将 .ps 转换为 .pdf,同时获取位置信息。

gswin32c.exe -dBATCH -dNOPAUSE  header.ps trash.ps
gswin32c.exe -sDEVICE=pdfwrite -dCompressPages=false -sOutputFile=test.pdf header.ps trash.ps

输出

currentpoint  x:247.0 y:300.0  pathbbox 249.015,298.992 400.066,349.184   text:Chris  currentrgbcolor:1.0,0.0,0.0( )
currentpoint  x:50.0 y:90.0  pathbbox 50.8682,89.2852 181.327,139.184   text:Fred  currentrgbcolor:1.0,0.0,0.0( )
currentpoint  x:150.0 y:200.0  pathbbox 150.867,184.298 304.154,247.673   text:Mary  currentrgbcolor:1.0,0.0,0.0( )
currentpoint  x:300.0 y:350.0  pathbbox 300.867,348.993 598.79,398.681   text:Mr. Green  currentrgbcolor:0.0,1.0,0.0( )
currentpoint  x:100.0 y:400.0  pathbbox 100.866,399.202 358.547,449.183   text:Mr. Blue  currentrgbcolor:0.0,0.0,1.0( )

头文件.ps

/mydict 5 dict def
mydict begin
/show 
    {
    (currentpoint ) print 
    currentpoint exch 10 string cvs ( x:) print print  10 string cvs ( y:) print print
    gsave dup false charpath flattenpath 

    (  pathbbox ) print 
    pathbbox  
    4 -1 roll 10 string cvs print (,) print 
    3 -1 roll 10 string cvs print ( ) print 
    2 -1 roll 10 string cvs print (,) print 
    10 string cvs print ( ) print 
    grestore
    (  text:) 10 string cvs print   
    dup print ( ) print
    ( currentrgbcolor:) print 
    currentrgbcolor
    3 -1 roll 10 string cvs print (,) print
    2 -1 roll 10 string cvs print (,) print
    10 string cvs print ( ) ==
    systemdict /show get exec
} def

垃圾.ps

%!PS-Adobe-3.0 
%%Title: mwe.ps
%%Pages: 001
%%BoundingBox: 0 0 595 842
%%EndComments
%%Page: 1 1
%%PageBoundingBox: 0 0 595 842
0 0 1 setrgbcolor
0 0 595 842 rectfill
1 0 0 setrgbcolor
247 371 100 100 rectfill
/Times-Roman findfont
72 scalefont
setfont
newpath
247 300 moveto (Chris) show
50 90 moveto (Fred) show
150 200 moveto (Mary) show
0 1 0 setrgbcolor
300 350 moveto (Mr. Green) show
0 0 1 setrgbcolor
100 400 moveto (Mr. Blue) show
showpage
于 2013-02-15T05:30:55.017 回答
0

文本已转换为矢量路径。249 299 43 50 /5D 开始第一个字母“C”,然后 289 300 是“h”,289 300 是“r”......

pswrite 所做的是消除了对字体的需求,因此当您的原始代码使用 /Times-Roman 时,蒸馏代码不需要任何字体,而是使用矢量绘制文本。

我不确定您到底在追求什么,但您可以尝试“ps2write”或“epswrite”作为“pswrite”的替代品。pswrite 用于写入 ps 级别 1 标准,而 ps2write 将写入 ps 级别 2 输出。没有人需要 ps 级别 1 了,所以级别 2 是可以接受的。epswrite 将写入封装后记 (eps)。

于 2013-02-13T15:48:38.620 回答