Pro 版本
Optimizer — 深入參考
本頁是 NextPDF\Pro\Optimizer 公開介面的深入參考。內容涵蓋分析協調器、最佳化層級、兩個掃描器,以及結果值物件。它說明參數、預設值、估算算術與失敗模式。分析是唯讀的:它會估算節省量,且不會產出任何輸出文件。請先閱讀 Optimizer 功能頁 以取得工作流程指引。
可用性與授權
標題為「可用性與授權」的區段此功能隨 NextPDF Pro(nextpdf/pro)出貨,並透過 Pro 層級的授權封套啟用。未持有該權利的部署不會載入此功能的類別。比較版本並取得授權。
Optimizer 沒有任何單功能授權旗標。這是一項 Pro 版本的功能。最佳化層級是一個執行階段參數,而非授權開關。
公開 API 介面
標題為「公開 API 介面」的區段composer require nextpdf/pro:^3nextpdf/premium 統合套件會安裝 nextpdf/pro 程式碼;此模組位於 NextPDF\Pro\Optimizer 命名空間之下。
| 符號 | 參數 | 預設行為 | 回傳 | 拋出或失敗於 | 備註 |
|---|---|---|---|---|---|
PdfOptimizer::__construct | OptimizationLevel $level = OptimizationLevel::Balanced | 以指定層級建立 optimizer | PdfOptimizer | 未宣告 | 自行建構其掃描器實例 |
PdfOptimizer::analyze | string $pdfData | 以設定的層級進行唯讀分析 | OptimizationResult | 輸入超過 100,000,000 位元組時拋出 OverflowException;PDF 資料無效時由掃描器拋出 InvalidArgumentException | 僅估算;不產出任何輸出文件 |
PdfOptimizer::withLevel | OptimizationLevel $level | 回傳一個採用所請求層級的新 optimizer | self | 未宣告 | 接收端實例維持不變 |
OptimizationLevel | 案例 Lossless、Balanced、Aggressive | 以字串為底的積極程度層級列舉 | — | — | 底層值 lossless、balanced、aggressive |
OptimizationLevel::label | none | 人類可讀的層級標籤 | string | 未宣告 | 供顯示使用 |
OptimizationLevel::imageQuality | none | 該層級的目標影像品質 | int | 未宣告 | 100、75 或 50 |
OptimizationLevel::deduplicateStreams | none | 該層級是否啟用去重 | bool | 未宣告 | 僅 Lossless 為 false |
OptimizationResult::__construct | int $originalSize, int $optimizedSize, int $objectsRemoved, int $imagesBefore, int $imagesAfter, float $processingTimeMs | 不可變的分析結果 | OptimizationResult | 未宣告 | 所有屬性皆為 public 且 readonly |
OptimizationResult::savedBytes | none | 原始大小減去預估最佳化後大小 | int | 未宣告 | 位元組 |
OptimizationResult::savedPercent | none | 大小縮減百分比 | float | 未宣告 | 原始大小為零時為 0.0 |
OptimizationResult::summary | none | 多行的人類可讀報告 | string | 未宣告 | 大小以 B、KB 或 MB 格式呈現 |
ObjectDeduplicator::findDuplicates | string $pdfData | 以 SHA-256 雜湊將相同的物件主體分組 | list<DuplicateGroup> | 缺少 %PDF 標頭、輸入超過 268,435,456 位元組,或物件標記超過 500,000 個時拋出 InvalidArgumentException | 僅回傳成員數為二以上的群組 |
ObjectDeduplicator::estimateSavings | list<DuplicateGroup> $groups | 將每個群組的重複數乘以物件大小後加總 | int | 未宣告 | 位元組 |
ImageRecompressor::analyzeImages | string $pdfData | 為每個影像 XObject 擷取中繼資料 | list<ImageAnalysis> | 缺少 %PDF 標頭時拋出 InvalidArgumentException | 略過未明確指定寬度與高度的物件 |
ImageRecompressor::suggestCompression | ImageAnalysis $image, OptimizationLevel $level | 建議一個濾鏡並估算節省量 | ImageCompressionSuggestion | 未宣告 | 取決於層級的啟發式規則;參見行為合約 |
DuplicateGroup::__construct | string $contentHash, list<int> $objectNumbers, int $objectSize | 不可變的重複群組記錄 | DuplicateGroup | 未宣告 | 第一個物件編號是保留的正規物件 |
DuplicateGroup::duplicateCount | none | 群組大小減去正規物件 | int | 未宣告 | 可透過合併移除的物件 |
ImageAnalysis::__construct | int $objectNumber, int $width, int $height, string $colorSpace, int $bitsPerComponent, string $filter, int $streamSize | 不可變的單一影像中繼資料記錄 | ImageAnalysis | 未宣告 | 欄位對應影像字典的項目 |
ImageAnalysis::estimatedDpi | float $displayWidthPt | 在指定顯示寬度下的有效 DPI | float | 未宣告 | 顯示寬度為零或負值時為 0.0 |
ImageAnalysis::isOverResolution | float $displayWidthPt, int $targetDpi = 300 | 標記超過目標 DPI 的降採樣候選 | bool | 未宣告 | 採嚴格大於比較 |
ImageCompressionSuggestion::__construct | int $objectNumber, string $currentFilter, string $suggestedFilter, int $estimatedSavings, string $reason | 不可變的建議記錄 | ImageCompressionSuggestion | 未宣告 | reason 是人類可讀的說明文字 |
進入點簽章
標題為「進入點簽章」的區段final class PdfOptimizer{ public function __construct( private OptimizationLevel $level = OptimizationLevel::Balanced, )
public function analyze(string $pdfData): OptimizationResult
public function withLevel(OptimizationLevel $level): self}enum OptimizationLevel: string{ case Lossless = 'lossless'; case Balanced = 'balanced'; case Aggressive = 'aggressive';
public function label(): string
public function imageQuality(): int
public function deduplicateStreams(): bool}final readonly class OptimizationResult{ public function __construct( public int $originalSize, public int $optimizedSize, public int $objectsRemoved, public int $imagesBefore, public int $imagesAfter, public float $processingTimeMs, )
public function savedBytes(): int
public function savedPercent(): float
public function summary(): string}final class ObjectDeduplicator{ public function findDuplicates(string $pdfData): array
public function estimateSavings(array $groups): int}final class ImageRecompressor{ public function analyzeImages(string $pdfData): array
public function suggestCompression( ImageAnalysis $image, OptimizationLevel $level, ): ImageCompressionSuggestion}行為合約
標題為「行為合約」的區段PdfOptimizer::analyze 接受原始 PDF 位元組,且為唯讀。它會先將不受信任的輸入限制在 100,000,000 位元組;輸入過大時會在任何掃描執行前拋出 OverflowException。接著,當層級允許時它會執行去重分析、一律執行影像分析,並將兩者彙整為單一個 OptimizationResult。withLevel 會回傳一個新的 optimizer;實例絕不會被變動。
層級語意
標題為「層級語意」的區段| 層級 | 目標影像品質 | 去重 | 用意 |
|---|---|---|---|
Lossless | 100% | 關閉 | 無品質損失;位元組穩定的輸出用意 |
Balanced | 75% | 開啟 | 中等的品質取捨;預設值 |
Aggressive | 50% | 開啟 | 最大幅度縮減;降採樣;可見的品質損失 |
Lossless 會略過去重,讓輸出得以維持位元組穩定。目標品質會作為下方影像建議算術的輸入。
去重分析
標題為「去重分析」的區段去重器會掃描世代為零的間接物件定義(從 N 0 obj 到 endobj)。每個主體會去除周圍的空白、以 SHA-256 雜湊,並依雜湊分組。因此僅在填補上有差異的定義仍會相符。只有成員數為二以上的群組才會被回傳。由於除正規物件之外的其餘皆可移除,每個群組的預估節省量等於重複數乘以單一主體大小。
影像分析
標題為「影像分析」的區段當物件的主體包含 /Subtype /Image(內部有無空格皆可)時,該物件會被視為影像。寬度與高度為必要;缺少任一者的物件會被略過。色彩空間預設為 DeviceRGB、每分量位元數預設為 8,而濾鏡在缺少時預設為空字串。串流大小是在 stream 與 endstream 標記之間量測;若找不到內嵌串流,則改用 /Length 值。
建議啟發式規則
標題為「建議啟發式規則」的區段- 在
Lossless層級,會保留目前的濾鏡,且預估節省量為零。 - 對於
DCTDecode來源,建議會以該層級的品質重新編碼。估算值為串流大小乘以(1 − quality/100)再乘以 0.5。 - 對於
FlateDecode來源,建議會轉換為DCTDecode。估算值在Balanced為串流大小的 40%,在Aggressive為 60%。 - 對於任何其他濾鏡或無濾鏡,建議會轉換為
FlateDecode。估算值為串流大小的 20%。
結果算術
標題為「結果算術」的區段- 移除的物件數等於所有重複群組中,超出正規首個物件之成員的總和。
- 總節省量等於去重節省量加上各影像建議的估算值。
- 預估的最佳化後大小為原始大小減去總節省量,並以零為下限。節省量為非負值,因此估算值絕不會超過原始大小。
- 最佳化後影像數會針對每個含有已分析影像的重複群組,扣除該群組的重複成員數。此計數以零為下限。
- 處理時間以單調時鐘量測,並以毫秒回報。
DPI 估算器會將像素寬度除以以英吋為單位的顯示寬度(每英吋 72 點)。顯示寬度為零或負值時會得出 0.0。過度解析度判定式會將估算值與目標值比較,預設為 300 DPI。
邊界案例與失敗模式
標題為「邊界案例與失敗模式」的區段analyze只會回報潛在可能。請以 Writer 模組產出最佳化後的輸出。- 空輸入,或未以
%PDF標頭開頭的輸入,會以InvalidArgumentException失敗。 - 超過 100,000,000 位元組的輸入會在協調器入口、任何掃描之前,以
OverflowException失敗。 - 去重器會獨立拒絕超過 268,435,456 位元組的輸入以及超過 500,000 個的物件標記。兩者皆以
InvalidArgumentExceptionfail-closed 拒絕;不會有任何內容被截斷或部分掃描。 - 只有世代為零的物件定義會參與。世代編號非零的物件不會被掃描。
- 沒有結尾
endobj標記的定義會被略過。 - 未明確指定寬度與高度的影像物件會被排除於影像報告之外。
- 所有節省量數字皆為源自物件中繼資料的啟發式估計,而非實際量測的重新壓縮結果。
- lossless 層級刻意只回報小幅縮減;它會保留品質並略過去重。
- 分析絕不會解碼、執行或轉譯嵌入的內容。它只會讀取物件結構與中繼資料。
- 唯一使用的密碼學原語是 SHA-256,用於重複內容分組。此模組未定義任何 FIPS 專屬行為。
一致性
標題為「一致性」的區段兩個掃描器皆作用於 ISO 32000-2:2020 的 PDF 物件與影像模型。去重以間接物件定義為目標;其識別碼結構定義於 ISO 32000-2:2020, 7.3.10,並於本頁的引用記錄中列出。影像分析會讀取影像字典明確指定的參數——寬度、高度與每分量位元數——依循 ISO 32000-2:2020, 8.9.4,同樣列於引用中。
這些陳述描述的是相對於所引用條款的能力。NextPDF 未持有任何一致性認證,且支援某條款並不構成認證主張。
開發備註
標題為「開發備註」的區段- 模組原始碼標註
@since 1.9.0;本參考記載的是nextpdf/pro3.1.0 出貨時的介面。 - 所有類別皆為
final;結果與分析記錄為 readonly 值物件。請建構新實例,而非變動既有實例。 - 預設層級為
Balanced。可透過建構子或 with 風格方法選擇其他層級。 - 入口的輸入界限由跨 NextPDF 各輸入介面共用的 Core 輸入大小防護所強制執行。
- 分析是以字串為基礎、作用於已在記憶體中的位元組。此模組不會進行任何檔案系統或網路存取。
- 內部機制細節保留於原始碼儲存庫的內部文件中,不在本手冊的範圍內。
出版邊界
標題為「出版邊界」的區段本頁僅記載外部可觀察的行為與受支援的公開 API 介面。內部命名空間路徑、輔助類別、機制表格、runbook 檔名與工單前綴皆不在範圍內。
另請參閱
標題為「另請參閱」的區段- Optimizer — 提供工作流程指引與程式碼範例的功能頁。
- Writer — Deep Reference — 產出最佳化後的輸出文件。
- Accelerator — Deep Reference — 以本模組語意進行批次最佳化並搭配 sidecar 卸載。