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 | 以给定级别构建优化器 | PdfOptimizer | 未声明 | 构造其自身的扫描器实例 |
PdfOptimizer::analyze | string $pdfData | 以配置级别进行只读分析 | OptimizationResult | 输入超过 100,000,000 字节时抛出 OverflowException;PDF 数据无效时由扫描器抛出 InvalidArgumentException | 仅估算;不产生输出文档 |
PdfOptimizer::withLevel | OptimizationLevel $level | 返回一个采用所请求级别的新优化器 | self | 未声明 | 接收方实例保持不变 |
OptimizationLevel | case Lossless、Balanced、Aggressive | 表示激进程度级别的字符串支撑枚举 | — | — | 支撑值为 lossless、balanced、aggressive |
OptimizationLevel::label | 无 | 人类可读的级别标签 | string | 未声明 | 用于显示 |
OptimizationLevel::imageQuality | 无 | 该级别的目标图像质量 | int | 未声明 | 100、75 或 50 |
OptimizationLevel::deduplicateStreams | 无 | 该级别是否启用去重 | bool | 未声明 | 仅 Lossless 为 false |
OptimizationResult::__construct | int $originalSize、int $optimizedSize、int $objectsRemoved、int $imagesBefore、int $imagesAfter、float $processingTimeMs | 不可变的分析结果 | OptimizationResult | 未声明 | 所有属性均为 public 且 readonly |
OptimizationResult::savedBytes | 无 | 原始大小减去预估优化后大小 | int | 未声明 | 字节 |
OptimizationResult::savedPercent | 无 | 大小缩减百分比 | float | 未声明 | 原始大小为零时返回 0.0 |
OptimizationResult::summary | 无 | 多行的人类可读报告 | 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 | 无 | 组大小减去规范对象 | 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 返回一个新的优化器;实例绝不会被改变。
级别语义
标题为“级别语义”的章节| 级别 | 图像质量目标 | 去重 | 意图 |
|---|---|---|---|
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 个对象标记的输入。二者均以
InvalidArgumentException快速失败关闭;不会截断或部分扫描任何内容。 - 仅生成编号为零的对象定义参与其中。生成编号非零的对象不会被扫描。
- 缺少闭合
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 接口面。内部命名空间路径、辅助类、机制表、运维手册文件名与工单前缀均不在范围内。
另请参阅
标题为“另请参阅”的章节- Optimizer — 提供工作流指导与代码示例的能力页。
- Writer — 深度参考 — 生成优化后的输出文档。
- Accelerator — 深度参考 — 以本模块的语义进行带旁路卸载的批量优化。