Pro редакция
Optimizer — глубокий справочник
Краткий обзор
Заголовок раздела «Краткий обзор»Эта страница — глубокий справочник по публичной поверхности NextPDF\Pro\Optimizer. Она охватывает оркестратор анализа, уровни оптимизации, два сканера и объекты-значения результатов. Она описывает параметры, значения по умолчанию, арифметику оценки и режимы отказа. Анализ доступен только для чтения: он оценивает экономию и не создаёт выходной документ. Сначала прочитайте страницу возможности Optimizer для рекомендаций по рабочему процессу.
Доступность и лицензирование
Заголовок раздела «Доступность и лицензирование»Эта возможность поставляется в составе NextPDF Pro (nextpdf/pro) и активируется лицензионной оболочкой уровня Pro. Развёртывание без этого права не загружает классы возможности. Сравните редакции и получите лицензию.
У Optimizer нет лицензионного флага отдельной возможности. Это возможность редакции Pro. Уровень оптимизации — параметр времени выполнения, а не лицензионный переключатель.
Публичная поверхность API
Заголовок раздела «Публичная поверхность API»composer require nextpdf/pro:^3Метапакет nextpdf/premium устанавливает код nextpdf/pro; этот модуль расположен в пространстве имён NextPDF\Pro\Optimizer.
| Символ | Параметры | Поведение по умолчанию | Возвращает | Бросает или отказывает с | Примечания |
|---|---|---|---|---|---|
PdfOptimizer::__construct | OptimizationLevel $level = OptimizationLevel::Balanced | Создаёт оптимизатор с заданным уровнем | PdfOptimizer | Ничего не объявлено | Создаёт собственные экземпляры сканеров |
PdfOptimizer::analyze | string $pdfData | Анализ только для чтения на настроенном уровне | OptimizationResult | OverflowException при вводе свыше 100 000 000 байт; InvalidArgumentException от сканеров при некорректных данных PDF | Только оценивает; не создаёт выходной документ |
PdfOptimizer::withLevel | OptimizationLevel $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::__construct | int $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::findDuplicates | string $pdfData | Группирует идентичные тела объектов по хешу SHA-256 | list<DuplicateGroup> | InvalidArgumentException при отсутствии заголовка %PDF, вводе свыше 268 435 456 байт или более чем 500 000 маркеров объектов | Возвращает только группы с двумя или более элементами |
ObjectDeduplicator::estimateSavings | list<DuplicateGroup> $groups | Суммирует количество дубликатов на размер объекта по группам | int | Ничего не объявлено | Байты |
ImageRecompressor::analyzeImages | string $pdfData | Извлекает метаданные для каждого image XObject | list<ImageAnalysis> | InvalidArgumentException при отсутствии заголовка %PDF | Пропускает объекты без явных ширины и высоты |
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. Оценка — 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/pro3.1.0. - Все классы
final; записи результата и анализа — readonly объекты-значения. Создавайте новые экземпляры вместо изменения. - Уровень по умолчанию —
Balanced. Выберите другой уровень через конструктор или метод в стиле with. - Ограничение размера ввода на входной двери обеспечивается защитой размера ввода Core, общей для всех поверхностей ввода NextPDF.
- Анализ строковый по байтам, уже находящимся в памяти. Модуль не выполняет доступа к файловой системе или сети.
- Внутренние детали механизма остаются во внутренней документации репозитория исходного кода и вне области этого руководства.
Граница публикации
Заголовок раздела «Граница публикации»Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов вне области.
См. также
Заголовок раздела «См. также»- Optimizer — страница возможности с рекомендациями по рабочему процессу и примерами кода.
- Writer — глубокий справочник — создаёт оптимизированный выходной документ.
- Accelerator — глубокий справочник — пакетная оптимизация с выгрузкой в sidecar с семантикой этого модуля.