跳转到内容

PostScript 常见问题解答/使用 PostScript

来自维基教科书,开放世界中的开放书籍

使用 PostScript

[编辑 | 编辑源代码]

我需要 PostScript 打印机吗?

[编辑 | 编辑源代码]

在以下几种情况下,PostScript 打印机是理想的选择:

  • 你需要打印包含已放置 EPS 文件的文档
  • 你从第三方接收打印作业,并且需要可移植的 页面描述语言
  • 你期望打印可变内容文档
  • 桌面打印机充当更昂贵的打印机或图像设定器的廉价校样机
  • 矢量页面描述比页面栅格图像要短得多
  • 你运行的是 类 Unix 系统,其中 PostScript 语言充当打印机 API。

带有非 PostScript 打印机的软件 RIP 正在成为 PostScript 打印机的一个很好的替代方案。与内置的 RIP 不同,软件和硬件可以轻松升级。主机操作系统还提供了更好的调试环境。

如何创建 PS 文件?

[编辑 | 编辑源代码]

PostScript 是一种低级的 页面描述语言。PostScript 图形模型基于表示元素:线条、曲线、字符、图像。它没有单词、段落、对齐、脚注等概念。大多数作者更喜欢在更高层次上工作,并从高级页面描述生成表示格式(PostScript、PDFPCL 等)。

TeX 是一种排版程序,专为高质量地编排包含大量数学和技术表达式的材料而设计。它已被许多作者和出版商采用,他们用来生成技术书籍和论文。它是由斯坦福大学的唐纳德·克努斯教授创建的,最初是为了准备他的书籍系列《计算机程序设计艺术》。

groff(GNU troff)软件是一个排版软件包,它读取混合有格式化命令的纯文本并生成格式化的输出。

Mac OSMicrosoft Windows 上的 PostScript 打印机驱动程序可以从传入的 GDI 调用生成 PostScript 文件。因此,所有可以打印的应用程序也可以生成 PostScript。但是,文件中的图形原语集将受到 GDI 图形模型的限制。大多数图形编辑器和 DTP 应用程序绕过 GDI 并直接生成 PostScript。这有助于生成更好的 PostScript,并为应用程序提供更灵活的图形模型。

有时,需要手动创建或修改 PS 文件。PostScript 文件可能很大,并且包含二进制数据。文本编辑器不应该扩展制表符或标准化行尾。emacs 是一个不错的选择,因为它可扩展并且包含 PostScript 主模式。

如何将 PS 文件发送到打印机?

[编辑 | 编辑源代码]

在类 Unix 系统上,你可以使用 lpr

lpr -S computer_name -P queuename filename.ps

在 Microsoft Windows 上,你可以将文件发送到打印机,如下所示:

copy /b filename.ps lpr1

copy /b filename.ps \\computer_name_or_ip\printersharename

一些打印机也支持 lpr 协议。

PrintFile 是一个免费的 GUI Windows 程序,它将文件复制到系统打印队列。它也可以从符合 DSC 的 PostScript 文件中选取页面。

Classic Mac OS 上,你可以将文件拖放到打印机图标上。

在屏幕上查看 PS 文件的最佳方法是什么?

[编辑 | 编辑源代码]

PostScript 文件是为顺序打印而设计的 - 图像通常存储为内联流,页面大小和分辨率是页面描述的一部分。

查看器应该以随机顺序和放大倍数浏览文档。这可以通过将 PostScript 转换为内部形式来实现,该内部形式允许直接访问页面元素,并快速裁剪不可见的物体。没有一个 PostScript 查看器以这种方式工作。

GSview 是由 Ghostgum Software 的 Russel Lang 开发的 Ghostscript 的免费图形界面。页面选择是通过 DSC 处理实现的;缩放是通过重新解释页面实现的。GSview 可用于 Win32、Win32s、OS/2 和 GNU/Linux。旧版本可用于 Win16。还有其他用于 Ghostscript 的图形 X 窗口前端 - 例如 mgv、Moonshiner 和 Okular。

PostScript 可以使用 Ghostscript、ps2pdf 在线、Distiller、PDFCreator 和其他几个程序轻松转换为 PDF。与 PS 查看器相比,PDF 查看器要多得多。此外,PDF 查看器通常比大多数 PS 查看器更友好,因此查看 PS 文件最方便的方法是先将其转换为 PDF 文件。最流行的免费 PDF 查看器是 Adobe Reader、Evince、Foxit Reader、MuPDF、Okular、PDF-XChange Viewer、Sumatra PDF 和 Xpdf。

如何将二进制 PostScript 文件发送到仅支持 ASCII 的打印机?

[编辑 | 编辑源代码]

许多网络打印机不接受包含二进制数据的 PS 文件。

有时不可能将文件重新创建为 7 位 ASCII,但任何文件都可以轻松地转换为 ASCII 流,并通过相应的解码过滤器执行。以下脚本将标准输入转换为十六进制流,并添加解码代码。所有 DSC 注释都将被隐藏,但大多数打印机都会忽略它们。该脚本在 bashGNU/Linux 系统上进行了测试。

#! /bin/sh
echo '%!'
echo 'currentfile /ASCIIHexDecode filter cvx exec'
od -A n -v -t x1
echo '>'

MS-DOS 和 Windows 的脚本版本必须从自身中读取 '>' 字符,因为 echo ">" 打印 ">"(带引号)。

@echo off
rem ">"
echo %%!
echo currentfile /ASCIIHexDecode filter cvx exec
od -A n -v -t x1
od -A n -v -t c -j 16 -N 1 %0

od(八进制转储)来自 GNU Textutils 包。它在所有默认的类 Unix 系统(包括 macOS)上可用,并且可以使用 Cygwin 或 MinGW 包在 Windows 上安装。

PostScript 实用程序可以使用 PostScript 语言轻松编程。以下程序读取输入文件或标准输入,压缩它,可选地使用 ASCII85 编码进行转换,然后写入输出文件或标准输出。该程序由 Ghostscript 运行,使用:

 gs -q [-dASCII] [-dLEVEL3] -- encode.ps [INFILE [OUTFILE]]

其中

-q 禁止将版权信息写入 stdout
-dASCII 选择 ASCII85 编码
-dLEVEL3 选择在 3 级中引入的 Flate 编码
encode.ps 是程序
INFILE 是输入文件,默认为 stdin
OUTFILE 是输出文件,默认为标准输出。
%!
% encode.ps - compress and encode PS file to reduce upload time.
% This won't work if the file contains multiple jobs separated by ^D
%
/stderr (%stderr)(w) file def
/error { stderr exch writestring } bind def
/closetarget <</CloseTarget true>> readonly def
%
/openfile  % fname mode -> file
{ { file } stopped
    { exch (Cannot open file: ) error error (w) eq { (for writing\n) } { (for reading\n) } ifelse error
      flush quit
    }
  if
} bind def
%
/main      % - -> -
{ mark shellarguments
    { counttomark 2 le
        { counttomark
            { { (%stdin)(r) file (%stdout)(w) file }
              { (r) openfile (%stdout)(w) file }
              { (w) openfile exch (r) openfile exch }
            }
          exch get exec dup                   % input output output
          //systemdict /ASCII .knownget dup { true eq and } if
            { //closetarget /ASCII85Encode filter
              (/ASCII85Decode filter)
            }
            { () }
          ifelse
          exch                                % input output () output
          //systemdict /LEVEL3 .knownget dup { true eq and } if
            { //closetarget /FlateEncode filter exch
              (/FlateDecode filter)
            }
            { //closetarget /LZWEncode filter exch
              (/LZWDecode filter)
            }
          ifelse
          concatstrings                       % input output output ()
          2 index (%!\ncurrentfile) writestring
          2 index exch writestring
          exch ( cvx exec\n) writestring
          exch 61440 string                   % output input buf
            { 3 copy readstring pop           % output input buf output buf
              dup () eq { pop pop exit } if
              writestring
            }
          loop
          pop closefile closefile false
        }
        { (Incorrect number of file name arguments.\n) error true
        }
      ifelse
    }
    { (Missing '--' preceding encode.ps\n) error true
    }
  ifelse
    { (Usage: gs -q -dASCII -dLEVEL3 -- encode.ps INFILE OUTFILE\n) error flush
    }
  if
} bind def
%
main clear quit

如果需要,可以在将文件下载到打印机之前进行 DSC 处理。开发一个基于 ASCII85 的 DSC 感知转换器留给读者作为练习。

如何打印 EPS 文件?

[编辑 | 编辑源代码]

封装 PostScript,或 EPS 文件,通常用于包含在可打印的 PostScript 或其他 EPS 文件中。与可打印的 PostScript 不同,它们可能具有

  • showpage 运算符未包含
  • 图像移出可打印区域
  • 图像大小过大或过小
  • PC 风格的标题和预览

因此,直接将 EPS 文件发送到 PostScript 打印机可能会导致 PostScript 错误或仅打印页面。

标准方法是在图形设计应用程序中将 EPS 放置在页面中,然后打印。

为了直接打印 EPS 文件,您需要添加一个 PS 标题,它将执行所有必要的调整。

cat header.ps file.eps | lpr

net.anastigmatix.Import 资源页面上给出了一个合适的标题作为示例。

如何检查 PostScript 文件是否有效?

[编辑 | 编辑源代码]

将文件发送到 PostScript 解释器。如果您喜欢结果,则该文件有效。PostScript 解释器包括

当然还有其他的,但这些是最简单/最便宜的获取方式。

事实上,这将只检查 PostScript 程序在经过测试的解释器上的正确性。不同的解释器提供非常不同的执行环境,这会使 PS 程序采用不同的分支。

PostScript 程序可能会产生意外的输出,而不会报告任何 PostScript 错误。在关键任务情况下,必须在激光打印机上打印并由设计人员签署的校样。

如何计算 PS 文件中的页面数?

[编辑 | 编辑源代码]

使用 bbox 设备解释文件并计算 HiResBoundingBox 行。

gs -q -dNOPAUSE -dBATCH -sDEVICE=bbox foo.ps 2>&1 | grep -c HiResBoundingBox

命令也比较快

yes | gs -q -dBATCH -sDEVICE=nullpage foo.ps | grep -c showpage

假设文档符合 DSC,可以直接在文档中计算 %%Page 注释。

grep -c %%Page: file.ps

如何确定哪些页面是彩色页面,哪些页面是单色页面?

[编辑 | 编辑源代码]

首先,您需要决定是什么使页面成为彩色页面。可能,单色页面在 CMY 分量的密度为零。要使用 Ghostscript 检查这一点,您需要选择一个真彩色 CMYK 设备,安装正确的 CRD 并光栅化文件。

如果任何像素在 CMY 平面中具有非零分量,则该页面为彩色页面。

如何仅打印 PS 文件中的某些页面?

[编辑 | 编辑源代码]

DSC(文档结构约定)旨在提供一种简单的方法来解析 PostScript 文档,重新排列页面,添加缺失的字体,替换图像等。虽然大多数程序生成 DSC 注释,但很少有程序使用它们。看来,即使是主要供应商也从未测试过 DSC 注释的正确性。

有时,声称 DSC 符合性的文档在修改后会因 PostScript 错误而失败。更糟糕的是,页面可能会以某种微妙的方式损坏。例如,可增量下载字体的某些字符可能会被静默替换为默认字符。

基于 DSC 注释的页面选择由 PrintFile 和 GSview 使用。

PDF 可以作为一种方便的中间格式,尤其是在多次执行页面提取时。您可以使用 Ghostscript 将文件转换为 PDF 并提取一定范围的页面,如下所示

ps2pdf input.ps output.pdf
gs -dFirstPage=1 -dLastPage=2 output.pdf

偶尔,其他图形格式可能比 PDF 效果更好。作者曾经编写了 bilist.cpp,将两个 A5 页面放在一张 A4 页面上,并将页面重新排列为一些旧 PCL 打印机的签名。

如何重新排列 PS 文件的页面以打印小册子?

[编辑 | 编辑源代码]

有几种方法可以解决这个问题。每种方法都有其优点。

直接操作保留了大多数 PS 结构,并且占用最少的处理器时间。不幸的是,它仅适用于符合 DSC 的 PostScript 文件。虽然大多数主流应用程序生成的 DSC 文件声称符合 DSC,但很少有文件经过这样的测试。例如,Microsoft PS 驱动程序默认情况下会生成不符合规范的文件。

来自 psutilspsselect 可以选择和重新排列符合 DSC 的 PS 文件中的页面。

转换为光栅图像是一种简单可靠的方法。例如,bilist.cpp 从 PCL 文件中提取页面,将页面重新排列为签名,并将它们放置成两页一页。Ghostscript 可用于 PostScript 到 PCL 的转换。

转换为 PDF 极大地简化了进一步的文档处理。PDF 文件中的页面可以以任何大小或顺序提取和打印。PostScript 文件可以使用多种应用程序转换为 PDF。例如,Ghostscript

ps2pdf input.ps output.pdf

要从 PDF 文件中提取一定范围的页面到另一个 PDF 文件,请使用

ps2pdf -dFirstPage#111 -dLastPage#666 input.pdf output.pdf

要从 PDF 文件中提取一定范围的页面并转换为 PS 文件,请使用

ps2ps -dFirstPage#111 -dLastPage#666 input.pdf output.ps

将 PDF 文件连接起来始终很安全,如下所示

gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=file.pdf \
   -c save pop -f file1.dsc file2.dsc file3.dsc ...

以上方法足以以任何顺序重新排列页面,但复杂的工作可以更有效地完成。PDF 文件可以转换为简单的符合 DSC 的 PS 文件。

pdf2dsc source.pdf output.dsc

输出文件将非常简单,因为所有复杂性都隐藏在 Ghostscript 库中。使用任何 DSC 实用程序、文本编辑器或脚本都很容易修改格式。

%!PS-Adobe-3.0
%...
/Page null def/Page# 0 def/PDFSave null def/DSCPageCount 0 def
/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def
GS_PDF_ProcSet begin pdfdict begin
file.pdf) (r) file { DELAYSAFER { .setsafe } if } stopped pop
pdfopen begin
%%Page: 1 1
1 DoPDFPage
%%Page: 2 2
2 DoPDFPage
%%Trailer
currentdict pdfclose end end end
%%EOF

更新后的文件可以转换回 PDF。

ps2pdf source.dsc result.pdf

DSC 文件使用 GS 库,如果 DSC 文件仅提供给 Ghostscript,则效果很好。要生成可移植的 PS 文件,请将其转换回 PS。

为什么我的 PS 驱动程序会生成彩色绘图,但生成灰度图像?

[编辑 | 编辑源代码]

当驱动程序为单色打印机生成 PostScript 流时,它通常会将彩色图像转换为灰度,以实现更好的传输时间、更快的渲染和更低的资源使用。将矢量对象转换为灰度不会节省太多空间或时间。因此,驱动程序将其留给 PostScript 解释器。

当作业打印到通用 PostScript 打印机驱动程序时,这个问题经常发生。通用驱动程序不是最好的驱动程序。它仅限于大多数打印机上可用的 PostScript 语言的通用子集。它是单色的,只有少量介质、字体选择,没有特殊功能。来自通用驱动程序的 PostScript 文件将在多种打印机上打印,但许多功能将缺失。

虽然看起来每台打印机都使用特殊的驱动程序,但实际上是同一个驱动程序配置用于不同的打印机。驱动程序从 PPD 文件中获取配置参数。如果可能,应使用本机 PPD 文件。Acrobat Distiller PPD 是生成不包含特定于供应商的功能的彩色 PostScript 文件的不错选择。

如何重新组合预分离的 PostScript 文件中的色版?

[编辑 | 编辑源代码]

对页面进行光栅化并将页面重新组合到复合文件非常简单。光栅化可以在每平面 8 位或每平面 1 位进行,具体取决于是否需要对复合图像进行任何颜色校正。

在矢量级别合并平面要困难得多。为此工作的唯一已知工具是来自 Creo(现已停产且不受支持)的 Seps2Comp Acrobat 插件。可以使用包括 Ghostscript 和 Acrobat Distiller 在内的许多程序将 PostScript 文件转换为 PDF。

如何删除围绕 n 页一页页面的黑色边框?

[编辑 | 编辑源代码]

Windows 驱动程序在进行 N-up 打印时会在虚拟页面周围生成黑框。这些框是在 `nupshowpage` 过程中绘制的。要删除这些框,必须修改此过程。在 3 级解释器上,`Hack-MSDriver-n-up` `IdiomSet` 可以在解释器加载作业文件时识别并替换此过程。不需要修改作业文件。要激活替换,需要将 idiom 文件复制到打印机或基于主机的解释器上的 `/Resource/IdiomSet/` 目录中。基于主机的解释器上的 PostScript 根目录可能与系统根目录不同。对于一次性替换,您也可以将 `IdiomSet` 文件附加到作业文件前面。

对于 1 级和 2 级解释器,必须使用任何文本编辑器从作业文件本身中删除 `framenup { ... } if` 片段。

%!PS-Adobe-3.0
%%Title: Hack-MSDriver-n-up
% Remove black frame around n-up pages generated by MS Driver
%%VMusage: 0 0
%%VMlocation: global
%%EndComments
%%BeginResource: IdiomSet Hack-MSDriver-n-up
currentuserparams /IdiomRecognition get
<</IdiomRecognition false>> setuserparams
currentglobal true setglobal
/Hack-MSDriver-n-up
<< 8 dict begin
   /; /grestore load def
   /V /div load def
   /@ /dup load def
   /~ /exch load def
   /rs /rectstroke load def
   /! /pop load def
   /? /ifelse load def
   /+ /translate load def
   /nupshowpage
     [ { ; $m concat
         framenup
           { pagemarg_nup 2 V nups V
             @ $m idtransform abs neg ~ abs neg ~
             paperw_nup paperh_nup rs
           }
         if
         /pgx_nup pgx_nup 1 add
         @ nx_nup eq
           { ! 0 store paperw_nup 1 nx_nup sub mul
             /pgy_nup pgy_nup
             1 add @ ny_nup eq
               { ! 0 store paperh_nup 1 ny_nup sub mul
               }
               { store paperh_nup
               }
             ?
           }
           { store paperw_nup 0
           }
         ? + $m matrix invertmatrix concat startpage
       } bind
       { ; $m concat
         /pgx_nup pgx_nup 1 add
         @ nx_nup eq
           { ! 0 store paperw_nup 1 nx_nup sub mul
             /pgy_nup pgy_nup
             1 add @ ny_nup eq
               { ! 0 store paperh_nup 1 ny_nup sub mul
               }
               { store paperh_nup
               }
             ?
           }
           { store paperw_nup 0
           }
         ? + $m matrix invertmatrix concat startpage
       } bind
     ]
   end
>> /IdiomSet defineresource pop
setglobal <</IdiomRecognition 3 -1 roll>> setuserparams
%%EndResource
%%EOF

如何在 US Letter 上打印 A4 或反之?

[编辑 | 编辑源代码]

待写。

该文档可以被缩放或只是移动。

psresize -PA4 -pletter a4.ps letter.ps
psnup -pletter -Pa4 a4file.ps letterfile.ps

修复页面设备,策略 3。

如何从 PostScript 文件中提取图形?

[编辑 | 编辑源代码]

PostScript 文档中的图形通常作为 EPS 文件包含,可以使用文本编辑器轻松提取。在符合 DSC 的文档中,EPS 文件使用文本编辑器进行封装。

%%BeginDocument
...
%%EndDocument

不要忘记 EPS 文件可以嵌套。

从 PostScript 文件中提取的 EPS 文件没有预览,可以使用 Ghostscript 重新生成预览。

如何将彩色 PostScript 转换为黑白?*

[编辑 | 编辑源代码]

如果您能运行 Perl,请查找 `bw_convert`,这是一个微小的 Perl 脚本,它将 PostScript 文件中的每个 RGB 颜色声明更改为黑色或灰色值。简单来说,它将 "setrgbcolor" 替换为 "pop pop pop 0 setgray"。可以在 bw_convert 中找到该脚本。该网站上没有记录脚本作者。然而,这个脚本实际上是一个关于如何不做事的绝佳例子;作者并没有真正理解 PostScript 是一种编程语言,简单的词法更改往往会失败,而在一开始添加一行额外的代码会更有效。该脚本也不处理图像、CMYK 数据或 2 级颜色运算符。

可以通过在 PostScript 文件开头添加以下行来完成类似的操作

/setrgbcolor {0.11 mul 3 1 roll 0.59 mul 3 1 roll 0.30 mul add add setgray} def

它将覆盖 `setrgbcolor` 并使用 `setgray` 计算灰度颜色。但这不会影响图像,也可能不会改变您想要更改的所有内容。也可能存在其他问题,因此不保证结果。

如何微调 RGB 到 CMYK 的转换,但保持其他对象不变?

[编辑 | 编辑源代码]

3 级 PostScript 有一种强大的方法可以微调设备相关颜色到设备无关颜色的校正:`UseCIEColor` 页面设备键和 `DefaultGray、DefaultRGB、DefaultCMYK` 颜色空间。

当 `UseCIEColor` 标志打开时,灰度、RGB 和 CMYK 颜色被解释为 `DefaultGray`、`DefaultRGB` 和 `DefaultCMYK` 颜色空间中的颜色。鲜为人知的是,设备颜色空间的数组形式(例如 `[DeviceCMYK]`)可以被定义为 `Default*` 资源,有效地禁用相应的转换。

CMYK 到设备无关颜色的转换通常是不希望的,因为会导致黑色生成信息的丢失。

如何获取日期和时间?

[编辑 | 编辑源代码]

对日期和时间的内置访问是通过 `currentdevparams` 和 `setdevparams` 在 `%Calendar%` 设备上进行的,该设备出现在 PostScript 语言参考手册 2012 版补充说明 中,用于 PostScript 语言级别 2。以下代码将日期和时间写入标准输出

(%Calendar%) /IODevice resourcestatus {
  pop pop (%Calendar%) currentdevparams
  dup /Running get {
    dup /Year get 4 string cvs print (-) print
    dup /Month get 2 string cvs print (-) print
    dup /Day get 2 string cvs print ( ) print
    dup /Hour get 2 string cvs print (:) print
    dup /Minute get 100 add 3 string cvs 1 2 getinterval print (:) print
    /Second get 100 add 3 string cvs 1 2 getinterval print (\n) print
  } {
    (Clock/calendar is present but not running.\n) print
  } ifelse
} {
  (No clock/calendar present.\n) print
} ifelse

该标准没有提供时区信息,时钟通常设置为本地时间。它的范围扩展到 2079 年。如果解释器在主机操作系统上运行,则操作系统可能会确定 `setdevparams` 是否能够真正设置时钟。

基于主机的 PostScript 解释器可以访问文件系统,包括命名管道和设备,因此可能性是无限的。这个例子是在 GNU+Linux 上使用特定解释器 Ghostscript 测试的。

在一个终端上键入以下内容

mkfifo foo
while true; do date >foo; done

在同一目录中的另一个终端上运行 `gs -dNODISPLAY`,然后键入

/t { (foo)(r) file closefile (foo)(r) file dup
    28 string readstring pop = closefile} def

现在,在 Ghostscript 提示符下键入 `t` 会显示当前时间,使用主机操作系统的 `date` 命令而不是 `%Calendar%` 设备。

PostScript 已被用来实现一个 HTTP 服务器

华夏公益教科书