跳转到内容
getnextpdf.com

Pro 版本

Optimizer — 深度参考

本页是 NextPDF\Pro\Optimizer 公共接口面的深度参考。它涵盖分析编排器、优化级别、两个扫描器以及结果值对象,并说明参数、默认值、估算算法与失败模式。分析是只读的:它估算节省量,不产生任何输出文档。请先阅读 Optimizer 能力页 以获取工作流指导。

此能力随 NextPDF Pronextpdf/pro)一同发布,并通过 Pro 层级的授权信封激活。缺少该授权的部署不会加载此能力的类。比较各版本并获取授权

Optimizer 没有逐功能的授权标记。这是一项 Pro 版本能力。优化级别是一个运行时参数,而非授权开关。

Terminal window
composer require nextpdf/pro:^3

nextpdf/premium 元包会安装 nextpdf/pro 代码;此模块位于 NextPDF\Pro\Optimizer 命名空间下。

符号参数默认行为返回抛出或失败于备注
PdfOptimizer::__constructOptimizationLevel $level = OptimizationLevel::Balanced以给定级别构建优化器PdfOptimizer未声明构造其自身的扫描器实例
PdfOptimizer::analyzestring $pdfData以配置级别进行只读分析OptimizationResult输入超过 100,000,000 字节时抛出 OverflowException;PDF 数据无效时由扫描器抛出 InvalidArgumentException仅估算;不产生输出文档
PdfOptimizer::withLevelOptimizationLevel $level返回一个采用所请求级别的新优化器self未声明接收方实例保持不变
OptimizationLevelcase LosslessBalancedAggressive表示激进程度级别的字符串支撑枚举支撑值为 losslessbalancedaggressive
OptimizationLevel::label人类可读的级别标签string未声明用于显示
OptimizationLevel::imageQuality该级别的目标图像质量int未声明100、75 或 50
OptimizationLevel::deduplicateStreams该级别是否启用去重bool未声明Losslessfalse
OptimizationResult::__constructint $originalSizeint $optimizedSizeint $objectsRemovedint $imagesBeforeint $imagesAfterfloat $processingTimeMs不可变的分析结果OptimizationResult未声明所有属性均为 public 且 readonly
OptimizationResult::savedBytes原始大小减去预估优化后大小int未声明字节
OptimizationResult::savedPercent大小缩减百分比float未声明原始大小为零时返回 0.0
OptimizationResult::summary多行的人类可读报告string未声明大小格式化为 B、KB 或 MB
ObjectDeduplicator::findDuplicatesstring $pdfData按 SHA-256 哈希将相同的对象体分组list<DuplicateGroup>缺少 %PDF 头、输入超过 268,435,456 字节,或对象标记超过 500,000 个时抛出 InvalidArgumentException仅返回成员数为二或以上的组
ObjectDeduplicator::estimateSavingslist<DuplicateGroup> $groups对每组累加重复数量乘以对象大小int未声明字节
ImageRecompressor::analyzeImagesstring $pdfData提取每个图像 XObject 的元数据list<ImageAnalysis>缺少 %PDF 头时抛出 InvalidArgumentException跳过没有显式宽度与高度的对象
ImageRecompressor::suggestCompressionImageAnalysis $imageOptimizationLevel $level推荐一个过滤器并估算节省量ImageCompressionSuggestion未声明依级别而定的启发式;见行为契约
DuplicateGroup::__constructstring $contentHashlist<int> $objectNumbersint $objectSize不可变的重复组记录DuplicateGroup未声明第一个对象编号是保留下来的规范对象
DuplicateGroup::duplicateCount组大小减去规范对象int未声明可通过合并移除的对象
ImageAnalysis::__constructint $objectNumberint $widthint $heightstring $colorSpaceint $bitsPerComponentstring $filterint $streamSize不可变的逐图像元数据记录ImageAnalysis未声明各字段镜像图像字典条目
ImageAnalysis::estimatedDpifloat $displayWidthPt在给定显示宽度下的有效 DPIfloat未声明显示宽度为零或负值时返回 0.0
ImageAnalysis::isOverResolutionfloat $displayWidthPtint $targetDpi = 300标记高于目标 DPI 的降采样候选bool未声明严格大于比较
ImageCompressionSuggestion::__constructint $objectNumberstring $currentFilterstring $suggestedFilterint $estimatedSavingsstring $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。随后,当级别允许时它运行去重分析,始终运行图像分析,并将二者聚合为一个 OptimizationResultwithLevel 返回一个新的优化器;实例绝不会被改变。

级别图像质量目标去重意图
Lossless100%关闭无质量损失;字节稳定的输出意图
Balanced75%开启适度的质量取舍;默认值
Aggressive50%开启最大缩减;降采样;可见的质量损失

Lossless 跳过去重,以便输出可保持字节稳定。质量目标会输入到下文的图像建议算法中。

去重器扫描生成编号为零的间接对象定义(N 0 objendobj)。每个对象体去除首尾空白后以 SHA-256 哈希,并按哈希分组。因此仅在填充上有差异的定义仍会匹配。仅返回成员数为二或以上的组。每组的预估节省量等于重复数量乘以单个对象体的大小,因为除规范对象外其余均可移除。

当对象体包含 /Subtype /Image(含或不含内部空格)时,该对象被视为图像。宽度与高度是必需的;缺少任一者的对象会被跳过。缺省情况下,颜色空间默认为 DeviceRGB、每分量位数默认为 8、过滤器默认为空字符串。流大小在 streamendstream 标记之间测量;当未找到内联流时,改用 /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/pro 3.1.0 中发布的接口面。
  • 所有类均为 final;结果与分析记录是 readonly 值对象。请构造新实例而非改变现有实例。
  • 默认级别是 Balanced。可通过构造函数或 with 风格方法选择其他级别。
  • 入口处的输入限制由跨 NextPDF 各输入面共享的 Core 输入大小防护强制执行。
  • 分析是基于内存中已有字节的字符串处理。本模块不进行任何文件系统或网络访问。
  • 内部机制细节保留在源码仓库的内部文档中,不在本手册范围内。

本页仅记录外部可观测的行为与受支持的公共 API 接口面。内部命名空间路径、辅助类、机制表、运维手册文件名与工单前缀均不在范围内。