3-Heights PDF Extract

3-Heights PDF Extract позволяет программно получать из PDF текст, координаты и параметры шрифтов, извлекать изображения с масками и сведениями о цвете, читать векторные контуры, метаданные, закладки, аннотации, вложения и структуру страниц. Через объектную модель документа можно последовательно обходить страницы и графические объекты, сохранять найденные ресурсы в файлы или память и передавать результат в поиск, базу данных, контроль долговременного хранения либо свой конвейер обработки.

Работа строится не вокруг ручного выделения области мышью, а вокруг предсказуемой цепочки объектов: документ открывается из файла, массива байтов или потока, затем выбирается номер страницы, после чего код получает страницу, её содержимое и очередной объект. Для каждого найденного текста, изображения или пути доступны связанные свойства — геометрия, матрица преобразования, состояние графики, цветовое пространство и идентификаторы ресурсов. Такой подход удобен там, где одинаковые правила требуется применить к сотням или миллионам файлов без визуального просмотра каждого документа.

Главная практическая задача перед разработчиком — не просто выгрузить символы, а сохранить смысл и происхождение данных. В PDF порядок операторов не обязан совпадать с порядком чтения, одно изображение может использоваться на нескольких страницах с разным масштабом, а визуально цельное слово иногда собрано из фрагментов разных шрифтов. Поэтому настройки формирования слов, обработку Unicode, координатную нормализацию, фильтрацию скрытых слоёв и контроль ошибок следует проектировать вместе с форматом выходных данных, а не добавлять после завершения экспорта.

Скачать 3-Heights PDF Extract

Оценка 9.7 Рекомендуем
  • Редактирование PDF
  • Русский интерфейс
  • Просто новичкам
Скачать бесплатно на Windows
Лучшая альтернатива
3-Heights PDF Extract
Оценка 8.5
  • Нет визуального редактора
  • Нужна лицензия
  • Нет встроенного OCR
Скачать 3-Heights PDF Extract
Загрузка начнётся после нажатия

Как устроен рабочий процесс извлечения

Базовый сценарий начинается с объекта Document. Метод Open принимает путь и, при необходимости, пароль; OpenMem работает с данными в памяти; OpenStream ожидает поток с произвольным доступом. После успешного открытия PageCount сообщает число страниц, а PageNo выбирает одну из них. Нумерация начинается с единицы, поэтому цикл обычно проходит диапазон от 1 до PageCount включительно. Свойство Page возвращает интерфейс выбранной страницы, а Page.Content — объект, который управляет обходом операторов её потока содержимого.

У Content есть два подхода. Специализированные методы GetNextText, GetNextImage и GetNextPath удобны, когда нужен один тип данных. Универсальный GetNextObject позволяет сохранить исходную последовательность объектов и различать текст, изображение, путь, сохранение и восстановление состояния графики, а также границы участков, зависящих от необязательного содержимого. Выбор метода влияет не на содержимое PDF, а на то, сколько контекста сможет сохранить результирующая модель.

Для надёжного экспорта стоит отделить четыре уровня. На уровне документа читаются метаданные и глобальные ресурсы. На уровне страницы фиксируются размеры, поворот и аннотации. На уровне содержимого определяется последовательность объектов. На уровне конкретного объекта извлекаются строка, пиксели, контур и параметры графического состояния. Если смешать эти уровни в одном цикле, легко сохранить один и тот же ресурс много раз или, наоборот, потерять различия между несколькими размещениями одного изображения.

Интерфейс и документация 3-Heights PDF Extract

Подключение к проекту и проверка окружения

В .NET-коде рабочие типы распределены по пространствам имён Pdftools.Pdf, Pdftools.PdfRenderer и Pdftools.PdfExtractNET. Документация показывает создание Document в конструкции using, что важно не только для аккуратного стиля: объект удерживает ресурсы парсера и должен освобождаться после закрытия файла. При ручном управлении жизненным циклом сначала вызывают Close, затем Dispose. В длинном серверном процессе освобождение нельзя откладывать до завершения приложения, иначе последовательная обработка больших пакетов будет накапливать нативную память.

Интерфейс .NET вызывает нативную библиотеку. Поэтому наличие управляемой сборки ещё не означает, что приложение может быть запущено: рядом с выходными файлами должен находиться подходящий нативный компонент. Для проекта AnyCPU загрузчик выбирает вариант, соответствующий реально запущенному процессу, а не разрядности операционной системы как таковой. Если служба запускается в 32-битном рабочем процессе на 64-битной системе, ей нужен 32-битный файл; при 64-битном процессе — 64-битный.

До обработки пользовательских документов полезно выполнить самотестирование на небольшом эталонном PDF. Тест должен создать Document, проверить действительность лицензии, открыть файл, прочитать PageCount и закрыть его. Такой запуск сразу отделяет проблемы развёртывания от ошибок конкретного документа. Если проверка выполняется во время сборки контейнера или образа сервера, отсутствующая библиотека, несовместимая архитектура и неустановленный ключ обнаруживаются до поступления очереди.

Интерфейс и документация 3-Heights PDF Extract

Программные интерфейсы и выбор способа вызова

Помимо .NET предусмотрены C, Java и COM. У них одна логическая модель, но различается управление памятью и регистрация. COM-компонент на Windows регистрируется через regsvr32; для 32-битного компонента на 64-битной системе используется соответствующая системная утилита из каталога SysWOW64. Java-обёртке требуется JAR в classpath и путь к нативной библиотеке в java.library.path либо в системном поисковом пути. В C разработчик внимательнее контролирует уничтожение возвращённых объектов и буферов.

Выбирать интерфейс следует по окружению, а не по кажущейся простоте примера. .NET удобен для служб, индексаторов и корпоративных приложений на C# или Visual Basic. Java подходит для существующего JVM-конвейера, но требует согласовать архитектуру JVM и нативной библиотеки. COM остаётся практичным для старых приложений, скриптов автоматизации и Visual Basic 6, однако регистрация компонента усложняет изолированное развёртывание. C даёт минимальный слой абстракции, зато предъявляет самые строгие требования к владению ресурсами.

Нельзя переносить имена типов между интерфейсами буквально. Например, объект документа в COM создаётся через зарегистрированный класс, в .NET — конструктором Document, а в Java — через соответствующую обёртку. При этом последовательность действий сохраняется: создать объект, открыть PDF, выбрать страницу, получить Content, извлечь объекты, обработать LastError при неудаче и гарантированно освободить ресурсы.

Интерфейс и документация 3-Heights PDF Extract

Открытие файла, памяти и потока

Open удобен, когда PDF уже лежит в файловой системе. Путь следует передавать после собственной проверки доступности, но итог открытия всё равно надо оценивать по возвращаемому Boolean: существующий файл может оказаться повреждённым, не-PDF или зашифрованным другим паролем. Не следует строить логику только на исключениях среды выполнения, поскольку ошибки разбора и лицензии доступны через LastError и LastErrorMessage.

OpenMem полезен, если документ получен из базы данных, очереди сообщений или сетевого слоя в виде массива байтов. Этот путь уменьшает число временных файлов и упрощает обработку конфиденциальных документов. Однако массив должен оставаться корректным на всё время открытия, а приложение должно ограничивать максимальный размер входа до передачи в парсер. Для большой коллекции разумнее не собирать все документы в память одновременно, а подавать их по одному.

OpenStream принимает поток с произвольным доступом. Требование random access принципиально: PDF хранит таблицы перекрёстных ссылок и объекты в местах, к которым парсер обращается не только последовательно. Поток, который умеет лишь читать вперёд, нужно сначала скопировать в seekable-буфер или временный файл. Пароль передаётся в том же месте, где открывается документ; если он неверен, результат Open будет ложным, а текст ошибки следует записать вместе с идентификатором задания, но не с самим паролем.

При повторном открытии тем же объектом ранее открытый документ закрывается. Тем не менее для пакетной обработки безопаснее явно завершать документ в блоке finally или using, чтобы путь ошибки не оставлял ресурс занятым. В логах полезно различать четыре стадии: получение входных байтов, открытие PDF, обход страниц и сохранение результата. Тогда сбой записи JSON не будет ошибочно классифицирован как проблема чтения PDF.

Страницы, нумерация и геометрия

PageNo принимает номер от 1 до PageCount. Установка нуля, отрицательного значения или номера за пределами документа является ошибкой логики вызывающего кода, поэтому диапазон лучше проверять до обращения к Page. Если пользователю разрешён выбор страниц, строку диапазона сначала разбирают в собственную нормализованную коллекцию номеров, удаляют повторы и только затем запускают извлечение.

Интерфейс Page возвращает MediaBox, CropBox, TrimBox, BleedBox и ArtBox. MediaBox задаёт физическую область носителя, CropBox — область, которую обычно показывает просмотрщик, а остальные рамки применяются в полиграфических процессах. Для координат пользовательского интерфейса чаще нужна CropBox, но для технической инвентаризации требуется сохранить все рамки: обрезанный за пределами CropBox текст может оставаться в содержимом и быть значимым для контроля утечек.

Rotate задаёт поворот страницы. Координаты объектов в PDF выражаются в системе пользователя, где начало обычно находится снизу слева; экранные координаты многих приложений начинаются сверху слева. Чтобы нарисовать найденный прямоугольник поверх визуализированной страницы, недостаточно поменять знак Y. Нужно учесть CropBox, поворот на 0, 90, 180 или 270 градусов и масштаб отображения. Те же правила относятся к прямоугольникам аннотаций.

Свойство HasColor можно использовать как быстрый признак для маршрутизации страниц, но оно не заменяет анализ отдельных цветовых пространств. DeviceColorant помогает получить сведения о специальных красителях. В отчёте о документе полезно хранить номер страницы, все рамки, поворот, цветовой признак и количество найденных объектов; такой паспорт облегчает поиск аномалий до детального извлечения.

Извлечение текста через Content

Метод GetNextText возвращает текстовые токены в порядке, в котором они встречаются при обходе содержимого. Часто создатель PDF записывает объекты в естественном порядке, но стандарт этого не требует. Заголовок может быть нарисован последним, колонки — чередоваться, а отдельные символы — располагаться в случайной последовательности. Поэтому поток GetNextText следует считать потоком токенов и координат, а не гарантированно готовым абзацем.

Свойство BreakWords управляет разделением на слова. Когда оно включено, API применяет внутреннюю логику границ и возвращает более удобные единицы для индексации. Когда нужно восстановить собственный порядок чтения или точно сопоставить символы с геометрией, полезнее сохранять более мелкие фрагменты и строить слова самостоятельно. Решение зависит от назначения: полнотекстовый поиск терпит небольшие расхождения в границах, а извлечение полей договора требует контролируемого алгоритма.

TextExtConfiguration выбирает конфигурацию извлечения текста, а SpaceFactor влияет на определение промежутка между токенами. Если слова склеиваются, коэффициент обычно уменьшают или увеличивают в соответствии с фактическими расстояниями и рекомендациями для конкретного документа; если внутри одного визуального слова появляются лишние пробелы, проверяют смену подмножеств шрифта, вертикальный сдвиг и ошибочные ширины глифов. Нельзя подбирать одно значение на одном файле и считать его универсальным для всей организации.

Reset возвращает обход содержимого к началу. Это позволяет сначала собрать статистику — например, диапазон размеров шрифта и количество изображений, — а затем вторым проходом извлечь только подходящие объекты. При двух проходах важно не забыть восстановить все настройки Content до одинакового состояния, иначе результаты будут различаться не только по фильтру.

Интерфейс и документация 3-Heights PDF Extract

Порядок чтения и восстановление строк

Для каждой текстовой единицы доступны BoundingBox, QuadPoints, XPos, YPos, Position, Width, FontSize, Rotation и TextMatrix. BoundingBox удобен для грубой фильтрации, но наклонный или повернутый текст точнее описывается четырёхугольником QuadPoints. TextMatrix сохраняет преобразование текста и позволяет различать горизонтальную строку, вертикальную надпись, повёрнутый штамп и символы, размещённые по диагонали.

Практический алгоритм восстановления строк начинается с нормализации координат по повороту страницы. Затем токены группируются по близости базовой линии и совместимому углу. Внутри группы они сортируются по направлению письма, после чего расстояние между соседями сравнивается с шириной пробела и размером шрифта. Только затем вставляются пробелы и переносы. Жёсткий порог в пунктах плохо работает на документах, где рядом встречаются текст размером 6 и 24 пункта; относительный порог устойчивее.

Многоколоночный документ требует дополнительного уровня. После формирования строк их можно кластеризовать по горизонтальным диапазонам, определять вертикальные разрывы и искать пересечения. Таблицы лучше не смешивать с обычными абзацами: короткие строки с повторяющимися X-позициями столбцов следует выводить как отдельную структуру. API предоставляет геометрию, но не обещает семантически готовую таблицу, поэтому правила колонок и ячеек остаются частью приложения.

Скрытый текст тоже может попасть в поток содержимого. Для контроля нужно учитывать режим визуализации текста, прозрачность, цвет и необязательные слои. Белый текст на белом фоне, текст с нулевой альфой или объект на выключенном слое может быть полезен для поиска, но не должен незаметно попадать в пользовательский экспорт. Сохраняйте признак видимости рядом с токеном вместо безусловного удаления: он помогает расследовать расхождения между визуальной страницей и индексом.

Unicode, сырые коды и лигатуры

UnicodeString предоставляет декодированную строку, а RawString — исходное представление кодов. В нормальном документе для поиска и JSON нужен UnicodeString. RawString следует сохранять в диагностическом режиме, когда декодирование выглядит подозрительно: он помогает понять, потеряны ли символы на уровне кодировки шрифта или ошибка возникла уже при последующей нормализации.

PDF может содержать карту ToUnicode, встроенную кодировку или только связи между кодом и глифом. Если смысл глифа не описан, визуально читаемый символ не всегда можно восстановить как букву. Простой тест — попытка выделить и скопировать текст в обычном просмотрщике: если копирование даёт бессмысленные символы, извлечение без OCR, вероятно, столкнётся с той же фундаментальной проблемой. Программа применяет интерпретацию кодировок и эвристики, но не может гарантированно угадать неизвестную письменность по форме глифа.

ExpandLigatures разворачивает лигатуры вроде объединённых пар символов в последовательность Unicode. Это полезно для полнотекстового поиска: слово с лигатурой должно совпадать с обычным вводом пользователя. Для судебно-технического отчёта, напротив, иногда важно сохранить исходный единичный глиф. Поэтому в модели данных разумно хранить нормализованную строку и, при необходимости, исходное значение отдельно.

TranslateSymbolic предназначен для случаев, когда TrueType-шрифт ошибочно помечен как символический. При включении кодовые точки из Private Use Area преобразуются по правилам, описанным для таких шрифтов. Настройка помогает в документах, где обычный текст искусственно оказался в частной области Unicode, но её следует проверять на значках и пиктограммах: настоящий символический шрифт не должен превращаться в случайные буквы.

Интерфейс и документация 3-Heights PDF Extract

Шрифты и типографические признаки

Интерфейс Font даёт BaseName, Type, Encoding, Charset, Flags, Ascent, Descent, CapHeight, среднюю, максимальную и отсутствующую ширину, наклон, ограничивающий прямоугольник и режим письма WMode. Эти свойства позволяют отличать основной текст от подписи, моноширинный код от пропорционального абзаца, вертикальное письмо от горизонтального и подозрительную замену шрифта от обычного подмножества.

FontFile и FontFileType позволяют получить встроенную программу шрифта и её тип. Такой экспорт применяют при технической инвентаризации, анализе проблем отображения и сохранении доказательной информации. Встроенный файл нельзя автоматически считать свободным для повторного распространения: права на шрифт определяются его лицензией. Безопасный процесс сохраняет его в закрытый диагностический каталог и связывает с хешем документа и номером объекта.

Widths возвращает ширины глифов. В сочетании со SpaceWidth, текстовой матрицей и фактическими позициями они помогают строить собственный алгоритм разделения слов. Если PDF содержит неправильные ширины, геометрический алгоритм должен доверять реальным координатам следующего токена больше, чем таблице шрифта. В отчёте об аномалии полезно фиксировать имя шрифта, наличие встраивания, кодировку и несколько проблемных кодов.

Флаг HasUnicodes показывает наличие Unicode-сопоставлений, IsCID — использование CID-шрифта. CID-шрифты нормальны для азиатских письменностей и больших наборов знаков. Проблемой становится отсутствие надёжного сопоставления между кодами и Unicode, особенно когда приложение пытается извлечь имена, артикулы или номера из документа, созданного нестандартным генератором.

Извлечение изображений: ресурс и размещение

В PDF изображение является ресурсом и может быть нарисовано много раз. Глобальный обход GetFirstImageResource и GetNextImageResource перечисляет уникальные ресурсы документа. GetNextImage в Content возвращает размещения в потоке страницы. Для каталога ресурсов нужен первый подход; для ответа на вопрос где на странице находится логотип — второй, потому что только размещение связано с текущей матрицей преобразования.

Image сообщает Width, Height, Samples, BitsPerComponent, Compression, ColorSpace, ObjNumber и признаки IsBitonal, IsMonochrome и IsColor. Метод GetResolution принимает TransformMatrix размещения и вычисляет фактическое разрешение на странице. У самого ресурса нет единственного DPI: один и тот же объект может быть маленькой иконкой на первой странице и крупным фоном на второй.

Store записывает изображение на диск, StoreInMemory сохраняет результат в память, а GetImage возвращает полученный массив байтов. При работе сервиса удобнее память, потому что она позволяет сразу вычислить хеш, отправить объект в хранилище и не создавать временные имена. Для больших изображений нужно ограничивать параллелизм и освобождать буферы после передачи, иначе пик потребления памяти окажется значительно выше размера исходного PDF.

ObjNumber полезен для дедупликации. Однако номер объекта уникален только внутри конкретного PDF. В междокументной базе ключ строят из хеша сохранённых байтов и параметров декодирования, а номер объекта сохраняют как ссылку на происхождение. Если приложение считает повторные размещения отдельными изображениями, оно должно дополнить ключ номером страницы и матрицей.

Интерфейс и документация 3-Heights PDF Extract

Компрессия, цвет и прозрачность изображений

Compression сообщает способ сжатия, включая сырой вариант и JPEG. Сохранение исходно сжатого потока предпочтительно, когда задача состоит в точном извлечении ресурса без изменения качества. Преобразование в универсальный формат требуется, если последующий компонент не понимает исходное цветовое пространство или маску. В отчёте стоит хранить исходный метод сжатия и формат результата отдельно, чтобы не принять конвертированный PNG за исходный ресурс PDF.

ColorSpace раскрывает цветовое пространство, число каналов, имена красителей, базовое пространство и таблицу Lookup для индексированных цветов. Методы и свойства RGB/CMYK в GraphicsState нужны для объектов страницы, а Image.ColorSpace — для самого изображения. ConvertToRGB упрощает использование в веб-интерфейсе, но преобразование DeviceCMYK зависит от цветовых профилей. Для управляемого цвета укажите подходящий ICC-профиль вместо безусловного применения профиля по умолчанию.

Mask и SMask возвращают обычную и мягкую маску прозрачности. Если сохранить только основное изображение, края логотипа могут стать чёрными, а полупрозрачные тени исчезнут. Правильный конвейер извлекает маску, проверяет размеры и число отсчётов, а затем либо сохраняет её отдельно, либо объединяет с изображением в формат с альфа-каналом. Информация об исходной маске всё равно должна остаться в метаданных экспорта.

Alternates перечисляет альтернативные представления, в том числе вариант, который может быть предпочтительным для печати. Их нельзя бездумно смешивать с основным ресурсом: приложение должно явно указать роль каждого файла. ChangeOrientation помогает скорректировать ориентацию сохранённого изображения, но геометрия размещения всё равно определяется матрицей страницы. Проверяйте результат на изображениях, повернутых и отражённых отрицательным масштабом.

Векторные пути и их растеризация

GetNextPath извлекает графические пути как строку операторов PDF. Это позволяет анализировать линии, прямоугольники, кривые и контуры без рендеринга всей страницы. В задачах распознавания таблиц горизонтальные и вертикальные сегменты можно сопоставлять с координатами текста. Для технической экспертизы путь хранится вместе с состоянием графики, иначе неизвестно, был ли он обведён, залит, прозрачен или использовался как отсечение.

ConvertPathToImage преобразует путь в изображение. PathImageResolution задаёт разрешение, PathImageBGColor — фон, PathImageAntiAlias — сглаживание. Этот режим полезен для миниатюр векторных печатей и значков, но не должен подменять исходное описание, если важна точность координат. Растеризация необратима: кривые превращаются в пиксели, а мелкие детали зависят от выбранного DPI.

BoundingBox содержимого даёт область, охваченную объектами, однако сложный путь может содержать точки за пределами видимого результата из-за отсечения. При поиске рамок таблиц нужно фильтровать короткие декоративные сегменты, учитывать толщину линии и объединять соседние отрезки с небольшими разрывами. Наличие прямоугольника ещё не означает ячейку: он может быть фоном, полем формы или элементом логотипа.

Универсальный обход GetNextObject особенно ценен для путей, потому что сохраняет команды Save и Restore графического состояния. Если брать только GetNextPath, приложение получает удобный список, но теряет часть контекста последовательности. Для аудита печатной графики и слоёв лучше использовать общий поток, а для извлечения иллюстраций — специализированный метод.

Состояние графики каждого объекта

GraphicsState описывает CTM, цвета заливки и обводки, цветовые пространства, толщину линии, типы соединений и окончаний, массив штрихов, прозрачность, режим наложения, intent рендеринга, overprint, параметры текста и активный шрифт. Это не декоративная справка: без состояния два одинаковых оператора пути могут давать совершенно разный визуальный результат.

FillColorRGB и StrokeColorRGB удобны для экранных задач, а варианты CMYK сохраняют печатные значения. Если исходное пространство другое, преобразование выполняется с цветовым профилем. Для контроля фирменных цветов лучше сохранять исходное ColorSpace и имена красителей, а RGB использовать только как представление для предварительного просмотра. Особые краски и DeviceN нельзя надёжно описать одной тройкой RGB.

FillAlphaConstant и StrokeAlphaConstant показывают прозрачность. BlendMode объясняет способ смешивания с фоном. Текст с нулевой или почти нулевой альфой может находиться в PDF, но быть невидимым. При создании поискового индекса стоит хранить его с признаком скрытости; при экспорте как видно на странице — исключать по прозрачности и режиму отображения.

FontSize, CharSpacing, WordSpacing, HorizontalScaling, Leading, TextRise и TextRenderingMode помогают воспроизвести типографику. TextRise обнаруживает верхние и нижние индексы. HorizontalScaling объясняет, почему номинальная ширина шрифта не совпадает с фактической. TextRenderingMode показывает, рисуется ли текст заливкой, обводкой, используется как контур отсечения или не рисуется. Эти данные особенно важны при сравнении визуального и логического текста.

Интерфейс и документация 3-Heights PDF Extract

Матрицы преобразования и точные координаты

TransformMatrix содержит шесть коэффициентов a, b, c, d, e и f. Они кодируют масштабирование, поворот, наклон и перенос. Свойства Orientation, Rotation, ScaleX, ScaleY, SkewX, SkewY, TransX и TransY предоставляют вычисленные значения, но исходные коэффициенты стоит сохранять для точного воспроизведения. Отрицательный масштаб может означать отражение, которое не видно по одному углу поворота.

Для изображения единичный квадрат преобразуется в параллелограмм размещения. Поэтому фактический размер на странице рассчитывается после применения CTM. Метод GetResolution использует именно эту матрицу. Для текста TextMatrix взаимодействует с текущей CTM и параметрами графического состояния; при построении подсветки нужно использовать геометрию, уже возвращённую интерфейсом текста, либо корректно перемножать матрицы в установленном порядке.

Ошибки порядка преобразований проявляются типично: прямоугольник совпадает по размеру, но находится в зеркальной точке; координата Y перевёрнута; надпись на странице с поворотом 90 градусов смещена на ширину листа. Тестовый набор должен включать четыре поворота страницы, повёрнутое изображение, отрицательный ScaleX, наклонный текст и CropBox, не совпадающий с MediaBox.

В выходной JSON удобно записывать две системы: исходные PDF-координаты и нормализованные координаты относительно видимой CropBox с началом сверху слева. Первая нужна для технической трассировки, вторая — для веб-интерфейса и разметки. Хранение только нормализованного прямоугольника затруднит повторный анализ, если позже изменится алгоритм учёта поворота.

Интерфейс и документация 3-Heights PDF Extract

Аннотации, ссылки и вложения на странице

Page.GetFirstAnnotations и GetNextAnnotation обходят аннотации. Интерфейс Annotation предоставляет тип, прямоугольник, цвет, содержимое, тему, дату, флаги, связанный файл и назначение ссылки. Прямоугольник хранится в исходных координатах PDF; для отображения его обрезают по CropBox и поворачивают вместе со страницей.

Флаги различают невидимые, скрытые, печатаемые, не масштабируемые, не поворачиваемые и не показываемые аннотации. Нельзя считать отсутствие видимой заметки отсутствием аннотации: скрытый объект может содержать текст или вложение. Для инвентаризации сохраняйте все аннотации, а для пользовательского представления применяйте фильтр видимости и печати отдельно.

Destination позволяет получить цель внутренней ссылки: страницу и параметры перехода. Документ также умеет разрешать именованные назначения через GetDestination. Внешние действия следует рассматривать как данные, а не выполнять. При построении карты документа внутренние ссылки связываются с номером страницы, а недействительные назначения отмечаются как ошибки структуры.

AttachedFile значим для аннотации типа FileAttachment. Такое вложение отличается от файлов, перечисленных на уровне документа, местом привязки и пользовательским значком. Экспорт должен включать номер страницы, прямоугольник аннотации, описание и метаданные файла. Имя вложения нельзя напрямую использовать как путь: сначала удаляют разделители каталогов, управляющие символы и конфликтующие имена.

Интерфейс и документация 3-Heights PDF Extract

Метаданные документа и XMP

Свойства Title, Author, Subject, Keywords, Creator, Producer, CreationDate и ModDate читают стандартные поля информационного словаря. Они полезны для каталога, но не всегда надёжны: генератор может оставить пустой заголовок, неверную дату или шаблонного автора. Поэтому метаданные дополняют вычисленными признаками — числом страниц, хешем файла, языком извлечённого текста и датой фактического поступления.

GetInfoEntry получает произвольную запись информационного словаря по имени. Пользовательские поля следует сохранять в отдельном словаре, чтобы они не конфликтовали со стандартной схемой. Значение может содержать строку в необычной кодировке; при ошибках декодирования журнал должен фиксировать имя ключа и безопасное диагностическое представление, не разрушая обработку всего документа.

GetXMPMetadata возвращает XMP, а GetXMPMetadataMem позволяет получить его в памяти. XMP представляет собой XML-пакет и может содержать Dublin Core, сведения PDF/A, идентификаторы, историю обработки и пользовательские пространства имён. Его следует разбирать XML-парсером с отключёнными опасными внешними сущностями, а не регулярными выражениями. Оригинальный пакет полезно хранить рядом с нормализованными полями.

При расхождении информационного словаря и XMP приложение должно иметь явное правило приоритета. Для проверки долговременного хранения обычно сохраняют оба значения и отмечают конфликт. Для поискового каталога можно выбрать XMP как более структурированную основу, но показывать пользователю предупреждение. Нельзя молча перезаписывать одно поле другим, если данные могут участвовать в юридическом процессе или долговременном хранении.

Закладки, назначения и метки страниц

GetFirstOutlineItem и GetNextOutlineItem обходят закладки. Элемент содержит заголовок и назначение, а иерархию следует сохранить как дерево, а не плоский список. Уровень вложенности помогает восстановить оглавление документа и разделить длинный текст на логические главы. Закладка может указывать не только на номер страницы, но и на позицию или масштаб, поэтому цель лучше хранить структурированно.

GetPageLabel возвращает видимую метку страницы. Она может отличаться от физического номера: титульные листы обозначаются римскими цифрами, приложения — буквами, а основная часть начинается с единицы после нескольких предварительных страниц. В поисковой выдаче полезно показывать одновременно физический номер и метку, иначе ссылка страница 3 может привести не туда, что ожидает читатель.

GetDestination разрешает именованные назначения. При проверке ссылок сначала строят словарь назначений, затем обходят аннотации и закладки. Цель считается корректной, если указывает на существующую страницу и допустимую область. Отсутствующая цель не должна останавливать извлечение текста, но попадает в раздел структурных ошибок.

Оглавление, метки и внутренние ссылки дают дополнительный контекст для индексирования. Токенам можно присвоить ближайшую предшествующую закладку, а фрагментам — логический номер страницы. Это улучшает поиск по руководствам и договорам, где одинаковые термины повторяются в разных разделах.

Слои и необязательное содержимое

PDF поддерживает optional content groups — слои, видимость которых может меняться в просмотрщике. Document.OcgCount и GetOcg перечисляют группы и их состояние. В потоке Content универсальный GetNextObject отмечает начало и конец участков, связанных с необязательным содержимым. Так можно сохранить принадлежность текста, изображения или пути к слою.

IgnoreOCM определяет, учитывать ли ограничения видимости при извлечении. Для поискового индекса иногда нужны все слои, включая выключенные; для экспорта как напечатано — только видимые по выбранной конфигурации. Правильный формат результата хранит имя или выражение членства слоя и рассчитанный признак видимости, чтобы позже применить другой фильтр без повторного разбора PDF.

Слои часто встречаются в чертежах, картах и многоязычных макетах. Два текстовых объекта могут занимать одно место, но относиться к разным языковым слоям. Простая сортировка координат склеит их в бессмысленную строку. Перед восстановлением чтения токены надо разделить по OCG или явно выбрать нужную конфигурацию.

Не следует путать слой с прозрачностью. Объект может принадлежать включённому слою, но быть невидимым из-за альфы или режима текста; либо быть на выключенном слое с обычным цветом. Итоговая видимость рассчитывается из нескольких факторов и должна быть отдельным полем модели.

Встроенные файлы и PDF-коллекции

GetFirstEmbeddedFile и GetNextEmbeddedFile перечисляют вложения документа. EmbeddedFile сообщает имя, описание, дату создания и изменения, MIME-тип, контрольную сумму, отношение ассоциации и признак начального документа коллекции. Store сохраняет поток на диск, StoreInMemory — в память. Если у записи нет встроенного потока, FileName может ссылаться на внешний файл, и попытка сохранить данные вернёт неуспех.

PDF/A-3 широко использует связанные вложения для исходных XML, таблиц или машинно-читаемых счетов. AssociationRelationship помогает отличить исходные данные, альтернативное представление, дополнение и данные. Экспорт должен сохранять это отношение; файл без контекста может потерять смысл. Одновременно проверяют MIME-тип, расширение и фактическую сигнатуру, потому что они могут не совпадать.

IsCollection показывает, организованы ли вложения как PDF-портфель. IsInitialDocument указывает начальный документ. При распаковке коллекции нельзя рассчитывать, что все имена уникальны. Безопасная схема создаёт идентификатор из номера объекта или хеша, хранит исходное имя как метаданные и записывает файлы в отдельный каталог без выполнения.

Контрольная сумма CheckSum в интерфейсе вложения представляет 16-байтовое значение, указанное в PDF. Её полезно сохранить, но для современной проверки целостности стоит дополнительно вычислить SHA-256 фактически извлечённых байтов. Несовпадение встроенной контрольной суммы с содержимым отмечается как аномалия, а не исправляется молча.

Интерфейс и документация 3-Heights PDF Extract

Сырые объекты PDF и словари

GetPDFObject предоставляет доступ к синтаксическому объекту PDF. PDFObject различает null, Boolean, integer, real, string, name, array, dictionary и stream; для словаря предусмотрены Begin, GetNext, End, GetKey и GetValue. Такой уровень нужен, когда требуемая запись не представлена отдельным свойством высокого уровня.

StringValue возвращает байтовое строковое значение, TextStringValue — декодированную текстовую строку в соответствии с правилами PDF. Выбор зависит от семантики ключа. Нельзя автоматически применять TextStringValue к произвольному бинарному потоку. Для массивов сначала читают Size, затем элементы; для косвенных объектов полезно сохранять ObjectNumber.

Доступ к сырому объекту увеличивает ответственность приложения. В PDF встречаются циклические ссылки, глубоко вложенные словари и большие потоки. Рекурсивный сериализатор должен иметь предел глубины, отслеживать уже посещённые косвенные объекты и не загружать каждый stream без необходимости. Иначе технический экспорт станет уязвимым к чрезмерному потреблению памяти.

Сложные функции в цветовых пространствах и некоторых графических записях не всегда представлены как готовые значения высокого уровня. Если приложение проводит аудит печати, оно должно отмечать неподдержанный сложный объект, а не подставлять ноль. Сырые данные сохраняются для дальнейшего анализа, но публичный JSON лучше ограничить безопасным, предсказуемым набором полей.

Цветовые пространства и профили

Документ может перечислять глобальные ресурсы цветовых пространств через GetFirstColorSpaceResource и GetNextColorSpaceResource. ColorSpace сообщает число каналов, имена красителей, базовое пространство, признаки Indexed и Monochrome и таблицу Lookup. Indexed хранит палитру, поэтому один индекс без таблицы не описывает цвет.

Для DeviceRGB и DeviceCMYK физический смысл цвета зависит от устройства. При конвертации библиотека ищет профили в системном каталоге цвета, в подкаталоге Icc рядом с нативной библиотекой или в пути, заданном переменной окружения. Если профили отсутствуют, используются создаваемые значения по умолчанию. В контролируемом полиграфическом процессе лучше поставлять утверждённые профили явно.

DeviceN и Separation могут содержать плашечные цвета. ColorantName помогает сохранить названия каналов. Преобразованный RGB годится для экранной миниатюры, но не для проверки наличия фирменной краски. В отчёте сохраняют исходное имя пространства, список красителей, число каналов, признак индексированности и профиль, применённый при конверсии.

Документные части PDF/X и PDF 2.0

DPartRoot открывает корень иерархии document parts. Эта структура используется в PDF/X и PDF 2.0 для логического деления документа. Узлы содержат имена уровней, диапазоны страниц и записи, которые можно связать с производственным заданием, главой или другим логическим сегментом.

При обходе дерева важно не предполагать фиксированное число уровней. NodeNameCount сообщает длину списка имён, а конкретные имена извлекаются по индексу. PageRange задаёт первую и последнюю страницу. Приложение проверяет, что диапазон находится внутри документа и не перевёрнут; ошибочная запись фиксируется, но не мешает обработать остальные части.

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

Compliance сообщает заявленное соответствие PDF/A. Этот признак не заменяет полноценную валидацию: чтение значения и проверка всех требований стандарта — разные задачи. Его можно использовать для маршрутизации документа к валидатору и для отчёта, но не для утверждения, что файл действительно соответствует профилю.

Шифрование, пароли и права доступа

IsEncrypted показывает наличие шифрования после успешного открытия. Пароль передаётся в Open, OpenMem или OpenStream. Приложение не должно записывать его в журнал, командную строку или имя временного файла. Для пакетной системы пароль получают из защищённого хранилища по идентификатору документа и удаляют из памяти настолько рано, насколько позволяет среда.

Неудачное открытие может означать неверный пароль, повреждение или неподдерживаемую структуру. LastError и LastErrorMessage дают диагностическую причину. Пользовательское сообщение должно быть короче технического журнала: например, не удалось открыть документ с кодом задания, тогда как внутренний лог содержит код ошибки, путь стадии и безопасные свойства файла.

Успешная расшифровка не отменяет политики организации. Техническая возможность извлечь текст или вложение не означает право распространять результат. Конвейер должен применять правила доступа к исходному документу и к производным данным одинаково, особенно если индекс содержит фрагменты конфиденциального текста.

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

Лицензия и контроль готовности

Без действительного ключа большинство операций интерфейса завершается ошибкой лицензии. LicenseIsValid позволяет проверить состояние до открытия очереди. SetLicenseKey задаёт ключ через интерфейс, а отдельный менеджер лицензий используется для установки ключа в окружении. Конкретный способ следует выбрать один и документировать, чтобы тестовая и рабочая системы не применяли разные способы получения.

Проверку лицензии лучше выполнять при старте процесса и передавать результат системе наблюдения. Если ключ отсутствует или недействителен, сервис не должен принимать задания и возвращать их в очередь бесконечно. Он переходит в состояние не готов, а оператор получает ясное сообщение. Повторная проверка по расписанию полезна для плавающей или обновляемой конфигурации, но не должна выполняться для каждого объекта страницы.

Лицензионная ошибка отличается от повреждённого PDF. В метриках заведите отдельные счётчики: license_error, open_error, parse_error, output_error. Это предотвращает ситуацию, когда истечение лицензии выглядит как массовое повреждение входящих документов.

Для тестов используйте документ с известным числом страниц и набором объектов. Проверка должна подтвердить не только LicenseIsValid, но и реальное чтение текста или изображения: окружение может иметь ключ, но не находить нативную библиотеку или цветовой профиль. Такой smoke-test выполняется после развёртывания и до переключения трафика.

Ошибки загрузки нативной библиотеки

В .NET распространённый симптом — TypeInitializationException при первом создании объекта. Внутреннее исключение DllNotFoundException указывает, что PDFParser.dll или одна из её зависимостей не найдена. Исправление начинается с проверки выходного каталога, настройки копирования, поискового пути процесса и фактической рабочей директории службы. Копирование DLL в произвольный системный каталог без учёта обновлений создаёт трудно диагностируемые конфликты.

BadImageFormatException обычно означает несовпадение разрядности: 32-битный процесс пытается загрузить 64-битную библиотеку или наоборот. Нужно проверить платформу сборки, настройку Prefer 32-bit, архитектуру пула приложений или контейнера и конкретный файл, который нашёл загрузчик. Имя одинаково, поэтому полезно выводить архитектуру процесса и абсолютный путь загруженного компонента.

В Java аналогичная ошибка сообщает о невозможности загрузить IA-32 DLL в AMD64 JVM либо наоборот. Согласовываются архитектура JVM, нативная библиотека и путь java.library.path. На Linux дополнительно проверяют LD_LIBRARY_PATH и зависимости через системный анализатор динамических библиотек. Отсутствие одной косвенной зависимости может выглядеть как отсутствие основного файла.

После исправления окружения удалите временные копии и перезапустите процесс: загрузчик может уже удерживать неудачно выбранную библиотеку. В CI полезно запускать минимальный пример из чистого каталога публикации, а не из каталога разработчика, где PATH и установленные компоненты скрывают пропущенный файл.

Интерфейс и документация 3-Heights PDF Extract

Обработка повреждённых и необычных PDF

Open возвращает false, если документ нельзя открыть. Не стоит сразу удалять такой файл: сохраните хеш, размер, исходный идентификатор и код ошибки, затем поместите его в карантин. Повторная попытка той же сборкой без изменения условий обычно бесполезна; она нужна только после обновления правил, пароля или самого файла.

Повреждение может затрагивать отдельную страницу или ресурс. Если документ открылся, обрабатывайте страницы в изолированных блоках и фиксируйте последнюю успешную. В зависимости от бизнес-задачи результат маркируется частичным, а не успешным. Полнотекстовый индекс не должен скрывать, что страницы после ошибки отсутствуют.

Чрезмерно сложные пути, огромные изображения и глубоко вложенные объекты требуют лимитов. Установите максимальное время на документ, число страниц, объём извлечённых байтов и глубину сырого обхода. Лимит является контролируемым завершением, а не внутренней ошибкой: в отчёте указывается конкретная причина и достигнутый порог.

Парсер не заменяет антивирус и песочницу. Вложения и извлечённые потоки сохраняются как данные, не открываются ассоциированными приложениями и не исполняются. Имена очищаются, расширение проверяется по сигнатуре, а доступ к каталогу результата ограничивается. Эти меры особенно важны для входящих документов из внешних каналов.

Производительность пакетной обработки

Самая дорогая ошибка — многократный разбор одного PDF для каждого вида данных. Если нужен текст, изображения и метаданные, документ открывают один раз, метаданные читают на уровне Document, затем в одном цикле проходят страницы. Второй проход оправдан, когда сначала требуется статистика для настройки или когда сохранение исходного порядка объектов важнее простоты.

Параллелизм организуют по документам, а не по объектам одной страницы. Каждый рабочий поток получает собственный Document и собственный выходной буфер. Не следует делить один экземпляр между потоками без явной гарантии интерфейса. Число работников ограничивают памятью, скоростью диска и размером изображений; увеличение потоков после насыщения хранилища лишь повышает задержку.

Дедупликация ресурсов уменьшает объём результата. Уникальные шрифты, изображения и цветовые пространства перечисляют на уровне документа и связывают с размещениями по номеру объекта. Для изображений дополнительно вычисляют SHA-256 извлечённых байтов. Однако не удаляйте информацию о каждом размещении: масштаб, страница, матрица и слой могут различаться.

Метрики должны измерять время открытия, число страниц, число текстовых токенов, объём изображений, время сериализации и пик памяти. Общая длительность без разбивки мало помогает. Если внезапно вырос этап извлечения изображений, можно проверить новые типы сканов; если замедлилось открытие, искать повреждённые таблицы ссылок или проблемы хранилища.

Память, временные файлы и освобождение ресурсов

StoreInMemory удобен, но каждый вызов создаёт массив байтов. При обработке страниц с десятками изображений нельзя складывать все массивы в список до конца документа. Сразу вычислите хеш, передайте байты в целевое хранилище и отпустите ссылку. Для результата JSON сохраняйте путь или идентификатор объекта, а не base64 больших файлов.

Store требует безопасной стратегии имён. Используйте внутренний идентификатор, а исходное имя храните отдельно. Запись выполняется в новый каталог задания с запретом перехода по символическим ссылкам. После успешной передачи результата временный каталог удаляется; после сбоя он либо очищается, либо сохраняется по политике карантина.

Document, Content и получаемые интерфейсные объекты связаны с нативными ресурсами. В .NET конструкция using вокруг Document задаёт очевидную границу. В COM ссылки освобождаются после использования, а в C вызываются предусмотренные функции уничтожения. Сборщик мусора не является заменой детерминированному освобождению в сервисе с постоянной нагрузкой.

Для очень больших файлов полезен поток с произвольным доступом, поддерживающий чтение с диска, вместо полного массива. Но временный сетевой поток без seek не подходит. Если вход поступил по HTTP, сначала сохраните его в контролируемое хранилище или seekable-буфер, проверьте размер и только затем открывайте.

Сканированные PDF и отсутствие OCR

Если страница состоит только из изображения скана, GetNextText не создаст содержательный текст, потому что буквенных объектов в PDF нет. Программа извлечёт растровый ресурс, его размеры, цвет и размещение, но не распознает символы на пикселях. Такой документ нужно передать OCR-компоненту отдельным этапом.

Определять необходимость OCR можно по сочетанию признаков: на странице нет текста или его очень мало, есть изображение, занимающее большую часть CropBox, и разрешение достаточно для распознавания. Одного условия нет текста недостаточно — чертёж или фотографический альбом могут не требовать OCR.

Гибридный PDF содержит и изображение, и невидимый OCR-слой. Тогда текст извлекается, но его качество следует проверять: сравнить объём текста с площадью страницы, долю заменяющих знаков, распределение координат и наличие очевидных повторов. Повторный OCR поверх существующего слоя может создать дубликаты, поэтому сначала оценивают извлечённый текст.

При передаче изображения в OCR сохраните матрицу и страницу. Координаты распознанных слов возвращаются в системе пикселей изображения и должны быть преобразованы обратно в PDF-координаты. Если изображение повернуто или отражено, простого масштабирования недостаточно. Исходная TransformMatrix обеспечивает правильное сопоставление.

Проектирование выходной модели данных

Минимальная запись текста должна содержать document_id, page_number, sequence, unicode_text, bounding_box, quad_points, rotation, font_id, font_size, visibility и layer_id. RawString добавляется только для диагностики. Строки и абзацы формируются поверх токенов, но исходные токены сохраняются, если требуется воспроизводимость.

Изображение описывается resource_id, object_number, width_px, height_px, bits_per_component, samples, compression, color_space_id, mask_id, hash и storage_key. Размещение хранится отдельно: page_number, sequence, matrix, calculated_dpi, layer_id и bounding geometry. Такая нормализация предотвращает повторное сохранение ресурса и не теряет позицию.

Документная запись включает стандартные метаданные, XMP, число страниц, версию формата, заявленное соответствие, признаки шифрования, линейности и коллекции, закладки, метки страниц, вложения и список ошибок. Каждое поле сопровождается происхождением — Info, XMP, вычисление или пользовательская система. Это помогает разрешать конфликты.

Версию схемы результата фиксируют явно. Если позже изменится алгоритм формирования слов или координат, старые записи остаются интерпретируемыми. В отчёте задания хранится версия схемы, конфигурация TextExtConfiguration, SpaceFactor, правила слоёв и идентификаторы цветовых профилей.

Практический сценарий: полнотекстовый индекс

Для индекса сначала открывают документ и создают запись метаданных. На каждой странице извлекают текстовые токены, нормализуют координаты, исключают либо маркируют невидимое содержимое и формируют строки. В индекс отправляют нормализованный текст, а геометрию сохраняют в отдельном хранилище для подсветки найденного фрагмента.

Нормализация включает Unicode NFC, контролируемую обработку переносов и пробелов, раскрытие лигатур и, при необходимости, исправление символических шрифтов. Не следует удалять всю пунктуацию на этапе извлечения: номера договоров, десятичные значения и адреса зависят от неё. Поисковый анализатор может применить собственную токенизацию позже.

Для многоязычного документа язык определяют по странице или фрагменту, а не только по метаданным. Слои разных языков разделяют. Закладки и DPart добавляют как поля раздела, метки страниц — как отображаемый номер. Ошибки декодирования уменьшают показатель качества документа и могут отправить страницу в OCR или ручную проверку.

При выдаче результата пользователь получает фрагмент и страницу. Подсветка строится по QuadPoints токенов, вошедших в совпадение, после учёта CropBox и Rotate. Если индекс сохранил только готовый абзац без токенов, точную подсветку восстановить трудно.

Практический сценарий: извлечение полей и таблиц

Для форм и счетов сначала определяется область интереса по координатам или опорной надписи. Токены фильтруются по пересечению с областью, затем сортируются по базовой линии. Поле справа от метки ищется по ограничению вертикального перекрытия и минимальному положительному расстоянию по X. Размер шрифта и слой помогают исключить фоновые шаблоны.

Таблица восстанавливается из линий и текста. Векторные пути дают кандидаты границ; повторяющиеся координаты строк и столбцов подтверждают сетку. Если границ нет, используются кластеры X-позиций и вертикальные интервалы. Объединённые ячейки требуют анализа непрерывности линий и ширины текста. API предоставляет все исходные объекты, но семантика ячейки определяется алгоритмом приложения.

Числовые значения сохраняют вместе с исходной строкой. Преобразование десятичного разделителя, валюты и даты выполняется после определения языка и шаблона документа. Если строка не прошла проверку, результат не подменяется нулём; создаётся ошибка поля с координатами и исходным текстом.

Шаблон извлечения тестируют на документах с другим размером страницы, поворотом, дополнительной строкой и изменённым шрифтом. Жёсткие координаты без привязки к CropBox и опорным элементам быстро ломаются. Более устойчивы относительные области и поиск по геометрии соседних токенов.

Практический сценарий: каталог изображений

Глобальные ресурсы изображений перечисляют один раз, сохраняют в память, вычисляют хеш и помещают в объектное хранилище. Затем по страницам обходят размещения и связывают object_number с ресурсом. Для каждого размещения вычисляют DPI, матрицу, видимость слоя и область на странице.

Фильтр миниатюр учитывает не только пиксельные размеры, но и площадь размещения. Большой ресурс может использоваться как крошечный значок; маленький — растягиваться на страницу. Логотипы часто повторяются, поэтому хеширование резко уменьшает объём. Фотографии и сканы сохраняют отдельно по типу цвета и фактическому разрешению.

Маски и альтернативные изображения обрабатывают как связанные ресурсы. Если конечный формат поддерживает альфа-канал, мягкая маска объединяется с основным изображением для просмотра, но оба исходных объекта остаются в техническом хранилище. Цветовое преобразование записывает использованный профиль.

Визуальная проверка выборки обязательна: несколько изображений с поворотом, CMYK, индексированной палитрой, SMask и повторным размещением. Автоматический тест сравнивает размеры, хеш и ожидаемое число размещений, но не обнаружит неверный цветовой профиль без эталонного рендера.

Практический сценарий: технический паспорт PDF

Паспорт собирает число страниц, рамки и повороты, версию PDF, заявленное соответствие PDF/A, метаданные Info и XMP, шрифты, цветовые пространства, изображения, слои, закладки, аннотации и вложения. Он не изменяет документ и подходит для предварительной маршрутизации в долговременное хранилище, печать или ручную проверку.

Правила могут отмечать отсутствующий заголовок, конфликт дат, незашифрованный конфиденциальный файл, внешнюю ссылку, скрытый текст, невстроенный шрифт, низкое DPI скана, CMYK без ожидаемого профиля или вложение с несовпадающим MIME-типом. Каждое правило должно ссылаться на конкретный объект и страницу.

Паспорт не заменяет валидатор стандартов. Свойство Compliance сообщает распознанный профиль, но полное соответствие требует проверки всех требований. В отчёте формулировка должна быть точной: заявлено/распознано вместо сертифицировано.

Результат удобно хранить в JSON и отображать в панели контроля. Тяжёлые двоичные ресурсы лежат отдельно, а паспорт содержит хеши и ссылки хранилища. Такой формат позволяет сравнивать две версии документа по структуре, даже если их байтовые хеши различаются.

Сравнение 3-Heights PDF Extract с аналогами

Решения в этой группе различаются не только языком программирования, но и уровнем абстракции. Одни предоставляют подробную объектную модель PDF, другие возвращают готовую структурированную выдачу из облака, а пользовательские редакторы рассчитаны на ручное извлечение. Выбор зависит от требований к конфиденциальности, объёму, геометрии, лицензированию и необходимости писать собственный алгоритм порядка чтения.

ПрограммаЛучше подходит дляГлавное ограничение
3-Heights PDF ExtractДетального программного извлечения объектов, координат, ресурсов и метаданных PDFНет встроенного OCR и визуального рабочего места
PDF CommanderРучной работы с PDF, редактирования и экспорта без разработки интеграцииНе предоставляет разработчику объектную модель для массового конвейера
Adobe PDF Extract APIОблачного получения структурированных элементов и таблиц с минимальной инфраструктуройДокументы передаются во внешний сервис и применяются квоты
Apache PDFBoxJava-проектов с открытым исходным кодом и собственными правилами разбораВосстановление сложного макета часто требует низкоуровневого кода
PyMuPDFБыстрых Python-сценариев, анализа страниц, текста и изображенийКоммерческое закрытое применение требует учёта условий лицензии
iTextJava и .NET-систем, где извлечение сочетается с созданием и изменением PDFAGPL или коммерческая лицензия и высокая сложность низкого уровня
Apryse SDKШироких кроссплатформенных PDF-решений с рендерингом и редактированиемБольшой коммерческий SDK избыточен для узкой задачи извлечения

Для автоматического конвейера, где важны исходные объекты, шрифты, цветовые пространства, слои и вложения, 3-Heights PDF Extract даёт наиболее предметную модель. PDFBox и PyMuPDF рациональны, когда команда предпочитает открытые экосистемы и готова самостоятельно решать порядок чтения. iText или Apryse выбирают, если извлечение — лишь часть большого процесса изменения PDF. Облачный API Adobe удобен при допустимой передаче документов и желании получить более готовую структуру. PDF Commander лучше подходит пользователю, которому нужно открыть файл и получить результат вручную без разработки.

Проверка качества извлечённого текста

Качество нельзя оценивать только числом символов. Минимальный набор метрик включает долю заменяющих знаков, управляющих кодов, слишком длинных последовательностей без пробелов, повторов, токенов за пределами страницы и невидимого текста. Для документов на известных языках добавляют долю слов из словаря, но не используют её как единственный критерий для артикулов и имён.

Геометрическая проверка выявляет перепутанный порядок. Строки не должны хаотично прыгать между колонками; BoundingBox токена должен пересекаться с CropBox после допустимого допуска; размер шрифта и ширина не должны быть отрицательными без объяснимого преобразования. Аномалии сохраняются с номером страницы и идентификатором объекта.

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

Ручная выборочная проверка остаётся необходимой. Автоматические метрики могут считать аккуратную, но неверную перестановку колонок приемлемой. Для каждого семейства генераторов PDF сохраняйте несколько визуально проверенных документов и ожидаемый результат.

Проверка изображений и цвета

Для каждого сохранённого изображения проверяют сигнатуру, размеры, число каналов и возможность декодирования независимым просмотрщиком. Если присутствует маска, создают контрольное составное изображение. Для CMYK и DeviceN сравнивают результат с эталонным рендером страницы, потому что технически успешная конвертация может дать неверный цвет.

DPI рассчитывается для конкретного размещения. Значение ниже порога отмечается только если изображение занимает существенную площадь и используется как содержательный скан или фотография. Маленький декоративный объект не обязан иметь высокий DPI. Для одного ресурса возможны разные значения на разных страницах.

Поворот и отражение проверяются по матрице. Тесты должны включать изображения, у которых отрицательный ScaleX или ScaleY, а также страницу с Rotate. ChangeOrientation применяют осознанно: сохранённый файл может быть визуально удобнее, но технический отчёт всё равно хранит исходную матрицу.

Дедупликация по хешу выполняется после определения, какие байты хешируются. Хеш исходного сжатого потока и хеш декодированного RGB различаются. Для точного происхождения полезен первый, для поиска визуально одинаковых ресурсов — второй или перцептивный хеш. Эти значения нельзя смешивать в одном поле.

Диагностика типичных проблем

Если слова склеены, проверьте SpaceFactor и фактические расстояния между токенами. Если внутри слов лишние пробелы, сравните шрифты, вертикальные смещения и Widths. Если порядок строк неверен, сортируйте по нормализованным координатам и разделяйте колонки. Если Unicode бессмысленен, изучите RawString, наличие ToUnicode и HasUnicodes; для скана направьте изображение в OCR.

Если изображение сохранено без прозрачности, извлеките Mask или SMask. Если цвета изменились, проверьте исходное ColorSpace и ICC-профиль. Если DPI кажется невероятным, убедитесь, что GetResolution получил матрицу именно текущего размещения, а не единичную матрицу ресурса. Если картинка перевёрнута, учитывайте отрицательные масштабы.

Если аннотация нарисована не там, преобразуйте Rect с учётом CropBox и Rotate. Если внутренняя ссылка не открывается, разрешите именованное назначение и проверьте диапазон страницы. Если вложение не сохраняется, выясните, есть ли у него встроенный поток или FileName указывает на внешний ресурс.

Если приложение падает при первом создании Document, изучите InnerException. DllNotFoundException требует проверки пути и зависимостей; BadImageFormatException — разрядности. Если все операции возвращают ошибки, отдельно проверьте LicenseIsValid. Если сбой возникает только на одном PDF, сохраните код LastError и отправьте файл в карантин, не повторяя бесконечно.

Безопасность конвейера

Входной PDF рассматривается как недоверенный двоичный файл. До открытия ограничивают размер, вычисляют хеш и присваивают внутренний идентификатор. Обработка идёт под учётной записью без лишних прав, в каталоге с квотой и запретом исполнения. Вложения и изображения не запускаются и не передаются системным обработчикам автоматически.

Имена файлов из PDF очищаются. Абсолютные пути, переходы .., разделители, управляющие символы и зарезервированные имена заменяются. Фактический путь строится только из внутреннего идентификатора. MIME-тип и расширение считаются подсказками, а решение о просмотре принимается после проверки сигнатуры.

XML из XMP разбирается безопасным парсером без внешних сущностей. Сырые словари обходятся с пределом глубины и объёма. Большие потоки не загружаются без необходимости. Тайм-аут и лимит извлечённых данных предотвращают блокировку работника на специально созданном документе.

Логи не содержат пароли и полный конфиденциальный текст. Для диагностики записываются хеш документа, номер страницы, тип объекта, код ошибки и короткий безопасный фрагмент, если политика это допускает. Производные данные наследуют класс доступа исходного PDF.

Совместимость и развёртывание

Интерфейсы доступны для Windows, Linux и macOS в поддерживаемых конфигурациях; конкретный нативный файл должен соответствовать системе и архитектуре процесса. .NET-пакет содержит управляемые и нативные компоненты для нескольких платформ, но поддержка среды выполнения не означает поддержку любой операционной системы, на которой она теоретически запускается. Перед выпуском проверяйте официальную матрицу для целевой системы.

Для Java требуется среда не ниже указанного в документации уровня и корректный classpath. Для COM необходима регистрация компонента и совпадение разрядности клиента. В .NET предпочтительно использовать механизм пакетов, который копирует зависимости в выходной каталог; при ручном развёртывании все требуемые DLL включаются вместе с приложением.

Контейнерный образ должен содержать нативные зависимости, цветовые профили и лицензионную конфигурацию. Самотестирование выполняется внутри итогового образа, а не на машине сборки. На Linux полезно проверить динамические зависимости основного файла до запуска сервиса.

Обновление проверяют на эталонном наборе. Сравнивают открытие, текст, геометрию, изображения, метаданные и ошибки. Даже улучшение эвристики формирования слов может изменить количество токенов, поэтому потребители результата должны быть готовы к версии схемы и повторному индексированию.

Когда программа подходит, а когда нужен другой инструмент

Она подходит, когда приложению нужен детальный доступ к существующему содержимому PDF: тексту с координатами, изображениям и их размещениям, графическим путям, шрифтам, цвету, аннотациям, слоям, метаданным и вложениям. Особенно оправдано применение в серверном индексировании, техническом аудите, хранилищах и специализированном извлечении полей.

Для пользователя, который хочет визуально открыть документ, выделить область, исправить страницу или экспортировать несколько фрагментов, рациональнее редактор с графическим интерфейсом. Здесь нет рабочего полотна и ручных инструментов. Для создания или глубокой модификации PDF нужен SDK, ориентированный на запись, а для распознавания сканов — OCR.

Если требуется готовая семантика таблиц и заголовков без разработки геометрического алгоритма, стоит рассмотреть сервис более высокого уровня. Если документы нельзя передавать внешнему провайдеру, подробная обработка в собственной инфраструктуре становится преимуществом. Если команда работает только на Java или Python и предпочитает открытый стек, PDFBox или PyMuPDF могут быть проще организационно.

Критерий выбора — стоимость всей интеграции, а не число методов. Учитываются точность на реальных документах, лицензия, поддержка целевой системы, управление нативными зависимостями, безопасность, скорость и объём кода для восстановления порядка чтения.

Итоговый рабочий чек-лист

Перед запуском проверьте лицензию, наличие нативной библиотеки, архитектуру процесса, цветовые профили и открытие эталонного PDF. Для каждого задания ограничьте размер и время, вычислите хеш входа и создайте изолированный каталог. Открывайте документ одним из методов, соответствующих способу поступления данных, и всегда проверяйте возвращаемое значение и LastError.

Сначала сохраните метаданные документа и глобальные ресурсы, затем пройдите страницы от 1 до PageCount. Зафиксируйте рамки, поворот, метку, аннотации и Content. Выберите специализированный или универсальный обход, настройте BreakWords, SpaceFactor, TextExtConfiguration, ExpandLigatures, TranslateSymbolic и правила OCG согласно назначению результата.

Текст храните с Unicode, геометрией, шрифтом, графическим состоянием и видимостью. Изображения разделяйте на ресурс и размещение, сохраняйте маски, цвет и фактический DPI. Пути связывайте с состоянием графики. Вложения очищайте по имени, проверяйте сигнатуру и хешируйте. XMP разбирайте безопасно, а сырые объекты обходите с лимитами.

После завершения закройте документ, освободите объекты и запишите метрики. Результат маркируйте как полный, частичный или ошибочный. Автоматические проверки дополните визуальной выборкой. Такой процесс превращает набор низкоуровневых PDF-объектов в воспроизводимые данные, пригодные для поиска, аналитики и последующей автоматизации без потери связи с конкретной страницей и ресурсом.