Перейти к содержимому
getnextpdf.com

Pro редакция

Optimizer — глубокий справочник

Эта страница — глубокий справочник по публичной поверхности NextPDF\Pro\Optimizer. Она охватывает оркестратор анализа, уровни оптимизации, два сканера и объекты-значения результатов. Она описывает параметры, значения по умолчанию, арифметику оценки и режимы отказа. Анализ доступен только для чтения: он оценивает экономию и не создаёт выходной документ. Сначала прочитайте страницу возможности Optimizer для рекомендаций по рабочему процессу.

Эта возможность поставляется в составе NextPDF Pro (nextpdf/pro) и активируется лицензионной оболочкой уровня Pro. Развёртывание без этого права не загружает классы возможности. Сравните редакции и получите лицензию.

У Optimizer нет лицензионного флага отдельной возможности. Это возможность редакции Pro. Уровень оптимизации — параметр времени выполнения, а не лицензионный переключатель.

Окно терминала
composer require nextpdf/pro:^3

Метапакет nextpdf/premium устанавливает код nextpdf/pro; этот модуль расположен в пространстве имён NextPDF\Pro\Optimizer.

СимволПараметрыПоведение по умолчаниюВозвращаетБросает или отказывает сПримечания
PdfOptimizer::__constructOptimizationLevel $level = OptimizationLevel::BalancedСоздаёт оптимизатор с заданным уровнемPdfOptimizerНичего не объявленоСоздаёт собственные экземпляры сканеров
PdfOptimizer::analyzestring $pdfDataАнализ только для чтения на настроенном уровнеOptimizationResultOverflowException при вводе свыше 100 000 000 байт; InvalidArgumentException от сканеров при некорректных данных PDFТолько оценивает; не создаёт выходной документ
PdfOptimizer::withLevelOptimizationLevel $levelВозвращает новый оптимизатор с запрошенным уровнемselfНичего не объявленоПринимающий экземпляр не изменяется
OptimizationLevelслучаи Lossless, Balanced, AggressiveСтроковый enum уровней агрессивностиБазовые значения lossless, balanced, aggressive
OptimizationLevel::labelнетЧитаемая метка уровняstringНичего не объявленоДля отображения
OptimizationLevel::imageQualityнетЦелевое качество изображения для уровняintНичего не объявлено100, 75 или 50
OptimizationLevel::deduplicateStreamsнетВключает ли уровень дедупликациюboolНичего не объявленоfalse только для Lossless
OptimizationResult::__constructint $originalSize, int $optimizedSize, int $objectsRemoved, int $imagesBefore, int $imagesAfter, float $processingTimeMsНеизменяемый результат анализаOptimizationResultНичего не объявленоВсе свойства публичные и readonly
OptimizationResult::savedBytesнетИсходный размер минус оценочный оптимизированный размерintНичего не объявленоБайты
OptimizationResult::savedPercentнетПроцентное сокращение размераfloatНичего не объявлено0.0, когда исходный размер равен нулю
OptimizationResult::summaryнетМногострочный читаемый отчётstringНичего не объявленоРазмеры форматируются как B, KB или MB
ObjectDeduplicator::findDuplicatesstring $pdfDataГруппирует идентичные тела объектов по хешу SHA-256list<DuplicateGroup>InvalidArgumentException при отсутствии заголовка %PDF, вводе свыше 268 435 456 байт или более чем 500 000 маркеров объектовВозвращает только группы с двумя или более элементами
ObjectDeduplicator::estimateSavingslist<DuplicateGroup> $groupsСуммирует количество дубликатов на размер объекта по группамintНичего не объявленоБайты
ImageRecompressor::analyzeImagesstring $pdfDataИзвлекает метаданные для каждого image XObjectlist<ImageAnalysis>InvalidArgumentException при отсутствии заголовка %PDFПропускает объекты без явных ширины и высоты
ImageRecompressor::suggestCompressionImageAnalysis $image, OptimizationLevel $levelРекомендует фильтр и оценивает экономиюImageCompressionSuggestionНичего не объявленоЭвристики, зависящие от уровня; см. контракт поведения
DuplicateGroup::__constructstring $contentHash, list<int> $objectNumbers, int $objectSizeНеизменяемая запись группы дубликатовDuplicateGroupНичего не объявленоПервый номер объекта — канонический сохраняемый объект
DuplicateGroup::duplicateCountнетРазмер группы минус канонический объектintНичего не объявленоОбъекты, удаляемые слиянием
ImageAnalysis::__constructint $objectNumber, int $width, int $height, string $colorSpace, int $bitsPerComponent, string $filter, int $streamSizeНеизменяемая запись метаданных отдельного изображенияImageAnalysisНичего не объявленоПоля отражают записи словаря изображения
ImageAnalysis::estimatedDpifloat $displayWidthPtЭффективный DPI при заданной ширине отображенияfloatНичего не объявлено0.0, когда ширина отображения равна нулю или отрицательна
ImageAnalysis::isOverResolutionfloat $displayWidthPt, int $targetDpi = 300Отмечает кандидатов на понижающую дискретизацию выше целевого DPIboolНичего не объявленоСравнение строго больше
ImageCompressionSuggestion::__constructint $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 возвращает новый оптимизатор; экземпляры никогда не изменяются.

УровеньЦелевое качество изображенияДедупликацияНазначение
Lossless100%Выкл.Без потери качества; намерение байтово-стабильного вывода
Balanced75%Вкл.Умеренный компромисс качества; по умолчанию
Aggressive50%Вкл.Максимальное сокращение; понижающая дискретизация; заметная потеря качества

Lossless пропускает дедупликацию, чтобы вывод оставался байтово-стабильным. Целевое качество питает арифметику рекомендаций для изображений ниже.

Дедупликатор сканирует определения косвенных объектов нулевого поколения (N 0 obj до endobj). Каждое тело очищается от окружающих пробелов, хешируется через SHA-256 и группируется по хешу. Определения, различающиеся только заполнением, поэтому всё равно совпадают. Возвращаются только группы с двумя или более элементами. Оценочная экономия на группу равна количеству дубликатов, умноженному на размер одного тела, поскольку все объекты, кроме канонического, можно удалить.

Объект считается изображением, когда его тело содержит /Subtype /Image (с внутренним пробелом или без него). Ширина и высота обязательны; объект без любой из них пропускается. Цветовое пространство по умолчанию — DeviceRGB, число битов на компонент — 8, а фильтр — пустая строка, если отсутствует. Размер потока измеряется между маркерами stream и endstream; когда встроенный поток не найден, вместо этого используется значение /Length.

  • На уровне Lossless текущий фильтр сохраняется, а оценочная экономия равна нулю.
  • Для источников DCTDecode рекомендация перекодирует с качеством уровня. Оценка — размер потока, умноженный на (1 − quality/100), умноженный на 0.5.
  • Для источников FlateDecode рекомендация преобразует в DCTDecode. Оценка — 40% размера потока на Balanced и 60% на Aggressive.
  • Для любого другого фильтра или его отсутствия рекомендация преобразует в FlateDecode. Оценка — 20% размера потока.
  • Число удалённых объектов равно сумме по всем группам дубликатов элементов сверх канонического первого.
  • Общая экономия равна экономии от дедупликации плюс оценки рекомендаций по каждому изображению.
  • Оценочный оптимизированный размер — это исходный размер минус общая экономия, с нижней границей ноль. Экономия неотрицательна, поэтому оценка никогда не превышает исходный размер.
  • Число изображений «после» вычитает для каждой группы дубликатов, содержащей проанализированное изображение, количество дублирующихся элементов этой группы. Число ограничено нулём снизу.
  • Время обработки измеряется монотонными часами и сообщается в миллисекундах.

Оценщик DPI делит ширину в пикселях на ширину отображения в дюймах (72 точки на дюйм). Нулевая или отрицательная ширина отображения даёт 0.0. Предикат превышения разрешения сравнивает оценку с целевым значением, по умолчанию 300 DPI.

  • analyze сообщает только о потенциале. Создавайте оптимизированный вывод через модуль Writer.
  • Пустой ввод или ввод, не начинающийся с заголовка %PDF, отказывает с InvalidArgumentException.
  • Ввод свыше 100 000 000 байт отказывает с OverflowException у входной двери оркестратора, до любого сканирования.
  • Дедупликатор независимо отклоняет ввод свыше 268 435 456 байт и более чем 500 000 маркеров объектов. Оба отказа fail-closed с InvalidArgumentException; ничего не усекается и не сканируется частично.
  • Участвуют только определения объектов нулевого поколения. Объекты с ненулевыми номерами поколения не сканируются.
  • Определение без закрывающего маркера endobj пропускается.
  • Объекты изображений без явных ширины и высоты исключаются из отчёта по изображениям.
  • Все цифры экономии — эвристики, выведенные из метаданных объектов, а не измеренные результаты рекомпрессии.
  • Уровень lossless намеренно сообщает о небольших сокращениях; он сохраняет качество и пропускает дедупликацию.
  • Анализ никогда не декодирует, не выполняет и не отрисовывает встроенное содержимое. Он читает только структуру объектов и метаданные.
  • Единственный используемый криптографический примитив — SHA-256, для группировки дублирующегося содержимого. Модуль не определяет поведения, специфичного для FIPS.

Оба сканера работают с моделью объектов и изображений PDF по ISO 32000-2:2020. Дедупликация нацелена на определения косвенных объектов; структура их идентификатора определена в 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.
  • Ограничение размера ввода на входной двери обеспечивается защитой размера ввода Core, общей для всех поверхностей ввода NextPDF.
  • Анализ строковый по байтам, уже находящимся в памяти. Модуль не выполняет доступа к файловой системе или сети.
  • Внутренние детали механизма остаются во внутренней документации репозитория исходного кода и вне области этого руководства.

Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов вне области.