跳轉到內容

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 伺服器

華夏公益教科書