Ghostscript 是一款免費的開放原始碼 PostScript 與 PDF 解析器,透過其內建的 pdfwrite 裝置來重新編寫 PDF,而使用它來壓縮 PDF 的典型做法是執行單一指令,在同一輪處理中對影像進行降取樣、重新壓縮資料串流,並重新嵌入字型。這個解析器會逐頁讀取輸入的 PDF,逐一分類其中的物件,然後輸出一個全新的檔案,而不是直接編輯來源檔,這就是為什麼對於影像為主的掃描檔案,它能省下相當多的位元組,但對於純文字文件則效果有限。這個做法本身很短,但從「我想要一個更小的 PDF」到「我已經安裝好 Ghostscript、設定好 PATH、並記住正確的參數」之間的落差很大,導致許多讀者在實際輸入指令之前,就先去尋找更簡便的途徑。對於那些體積主要來自內嵌照片的 PDF 來說,那條更簡便的路徑就是一個以分頁為基礎的工具,它會在記憶體中開啟檔案、找出其中的 JPG,只針對那些能安全縮小的影像重新編碼,最後再交回經過驗證的結果。

use ghostscript to compress pdf
想用 Ghostscript 壓縮 PDF?先試試這個

Ghostscript 命令列實際改變了什麼

Ghostscript 能壓縮其他工具幾乎無法動到的 PDF,原因在於它並非就地編輯檔案。設定 -sDEVICE=pdfwrite 後,每一頁都會被解析,內部物件會依類型分類,再從解析結果產生一份全新的 PDF。輸出裝置支援一組預設的設定組合,可以一次套用多個參數,因此你通常不必個別微調每一項。

預設組合參數影像目標典型用途
screen-dPDFSETTINGS=/screen~72 dpi,高度 JPEG 壓縮僅供螢幕檢視
ebook-dPDFSETTINGS=/ebook~150 dpi,中度 JPEG 壓縮電子閱讀器與一般分享
printer-dPDFSETTINGS=/printer~300 dpi,輕度 JPEG 壓縮辦公室列印
prepress-dPDFSETTINGS=/prepress~300 dpi,近乎無損印刷生產

在底層,每個預設組合會展開成一串更長的參數,用來控制影像降取樣、JPEG 品質、字型嵌入政策,以及資料串流篩選器。一個典型的 screen 等級指令看起來像這樣:

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dBATCH -sOutputFile=out.pdf in.pdf

-dNOPAUSE 與 -dBATCH 參數讓 Ghostscript 可以無人值守地執行,輸出參數則指向新檔案。如果你不想使用預設值,可以覆寫個別參數——例如 -dColorImageResolution=72、-dGrayImageResolution=72、-dMonoImageResolution=150、-dJPEGQ=70——自行調整清晰度與檔案大小之間的取捨。

命令列方式在哪個環節會造成阻礙

第一個障礙是安裝上的摩擦。在 Debian 與 Ubuntu 上,套件名稱是 ghostscript,會一併安裝幾個相依套件;在 Fedora 與 RHEL 上,則是透過 dnf 安裝對應的指令;在 Windows 上,則需從專案網站下載 GPL 版本,並將其 bin 資料夾加入 PATH。對熟悉終端機的人來說這些都不困難,但對只想在附加到 email 前把檔案變小的人而言,就是一道門檻。

第二個障礙在於完整重新渲染對文件的意義。由於 Ghostscript 會解析輸入並寫出新的 PDF,像內嵌的 ICC 色彩描述檔、表格欄位狀態、已簽署的簽章字典,以及部分註解類型,可能會以細微或出乎意料的方式被改變。對一份印刷報告的掃描檔來說這無關緊要;但對經過稽核的 PDF、帶有簽章欄位的合約,或必須維持色彩管理完整性的印刷用檔案而言,重新編寫後的檔案可能已不再與原稿相符,這就是實實在在的風險。Compress PDF 工具採相反的做法,只處理特定一類物件,文件其餘部分則完全保持原樣。

第三個障礙是回饋機制。命令列的做法會在執行完畢時通知你,但不會顯示壓縮前後的預覽,也不會驗證重新編寫後的 PDF 在接收者使用的檢視器中是否仍能正常開啟。如果某組參數產生了毀損的檔案,你往往要等到對端才會發現。對進階使用者來說這沒什麼,但對大多數讀者來說,這會促使他們選擇一條能在分享檔案前就先曝露問題的路徑。

改用瀏覽器在本機壓縮 PDF

對於體積主要來自內嵌照片或掃描頁面的 PDF 來說,有一個步驟更少的方式能達到相同目的:在瀏覽器分頁中開啟 Compress PDF,把檔案拖入,讓該分頁找出並重新編碼其中的 JPG。PDF 會被讀入記憶體,逐一列舉影像物件,只有通過嚴格資格條件的才會被替換成更小的重新編碼版本。來源檔案從不離開瀏覽器分頁;讀取、解碼、重新編碼與組裝都在本機執行,結果會先以 PDF 檢視器重新開啟,才會顯示下載連結。

資格條件刻意設得很嚴格。工具只處理使用 DeviceRGB 或 DeviceGray 色彩資料、未經遮罩、且沒有解碼參數的 DCTDecode JPG 資料串流。JPEG 2000 (JPX)、CMYK、Indexed 色彩、遮罩影像、ImageMask 影像,以及任何帶有解碼陣列的影像都會被排除在外——這些會直接略過,而不是用猜測的方式重新編碼。如果某張候選的重新編碼 JPG 實際上並未比原來位元組資料串流更小,就會保留原影像。如果沒有任何合格影像能縮小,工具會回傳一個誠實的錯誤訊息,而不是交回一個名實不符的檔案。單次執行的限制包括:單一 PDF 上限 25 MB、合格影像物件最多 80 個、影像解碼後總尺寸 100 megapixel;超過任何一項上限的文件,這一版的工具將不予接受。

如何在瀏覽器中壓縮 PDF

  1. 選擇一個不超過 25 MB 的本機 PDF。超過上限的檔案會在輸入階段就被拒絕,因此若超出請先縮小。
  2. 開啟 Compress PDF 並選取檔案。不會上傳任何資料;位元組會載入當前分頁中。
  3. 等待工具逐一檢查 PDF 中的影像 XObject,只針對合格的 JPG 在平衡品質與最長邊 1400 px 的最大尺寸下重新編碼。
  4. 查看執行後顯示的輸入與輸出大小。如果輸出沒有比輸入更小,就不會提供下載。
  5. 只有在比較兩個大小、確認結果符合需求後,才下載通過驗證的 PDF。原始檔案在磁碟上不會被更動。

驗證步驟是多數命令列流程省略的部分。在合格的 JPG 被替換、新 PDF 寫出之後,會以基於 Mozilla PDF.js 函式庫的檢視器重新開啟,確認頁數仍然一致,才會顯示下載連結。這能防範重新編碼的影像資料串流產生毀損 PDF 的情況,否則使用者往往要等到檔案在下游開啟失敗時才會發現。

瀏覽器工具改變了什麼,又保留了什麼

這個工具接受的取捨很直觀:以縮小內嵌 JPG 為代價,保留文件其餘結構。由於工具只會在原本的間接參照位置上重寫特定的影像資料串流內容,從不重建外圍的頁面樹狀結構,因此頁面內容、頁數、文字、連結、向量物件、表格欄位、註解與詮釋資料都會完整保留。不支援的影像物件會被略過而非轉檔,因此一份混雜 CMYK 照片、標誌與向量圖形的 PDF,會在照片頁面上縮小,其他部分則維持不變。

這也代表這個工具有明確的「不適用」情境。純文字的 PDF——例如合約、文章、從文書處理器匯出且沒有內嵌照片的報告——通常無法縮小,因為沒有合格的 JPG 可供重新編碼。以 JPEG 2000 掃描為主的文件也無法縮小,原因相同:JPXDecode 在排除清單上。在這些情況下,檔案大小取決於影像格式與 PDF 本身的開銷,而非工具能介入的部分,而誠實的答案是這時候該用 Ghostscript 或專業的桌面 PDF 最佳化工具,而不是步驟較少的替代方案。

何時 Ghostscript 或桌面最佳化工具仍是較佳選擇

當瀏覽器工具嚴格的資格清單無法有效縮減檔案時,就是 Ghostscript 重新派上用場的時候。如果 PDF 以文字為主、以 JPEG 2000 為主、採用 CMYK 色彩,或必須以歸檔等級的標準重現,那麼使用 /printer 或 /prepress 設定的 pdfwrite 裝置可以重新編寫資料串流、壓平透明度、重新嵌入字型,這些都是只處理 JPG 的工具無法做到的。安裝與終端機操作的成本,就是換來這種處理廣度的代價。

對於體積主要來自影像、只求符合附件大小限制的 PDF,通常的處理順序是:先試 Compress PDF,因為它在本機執行、幾秒內就能完成;只有在結果仍然太大時,才退而求其次使用 Ghostscript 指令或桌面最佳化工具。保留原始檔案、在平常使用的 PDF 檢視器中檢視輸出,並在分享較小的版本前以 100% 縮放仔細比對幾頁——這個簡單的檢查能抓出那種重新編碼後照片柔化過頭、寧可保留原始位元組的罕見情況。如需進一步了解「瀏覽器優先」的做法,以及停留在單一分頁內會帶來哪些改變,請參閱如何在瀏覽器中輕鬆壓縮 PDF。

若想深入了解,請參閱使用 Preview 壓縮 PDF:試試瀏覽器替代方案。