Почему изображения, взятые из PDF-файла, отличаются от изображений на странице?
Изображения с прозрачностью можно хранить отдельно в виде основного изображения и мягкой маски. Затем используйте Pillow для создания PNG RGBA, вставьте PDF-файл в память и подведите итоги основного изображения и SMask. Извлечение основных байтов изображения не равнозначно получению эффекта полной прозрачности и не равнозначно восстановлению всех экземпляров отображения на странице.
— Извлечение основных байтов изображения не означает получения эффекта полной прозрачности и не означает восстановления всех экземпляров отображения на странице.
- Одна и та же базовая карта может быть повторно использована на нескольких страницах, при этом только часть ее отображается через BBox и матрицу, а полная большая карта получается путем прямого извлечения.
— Пример кода создает входные данные в памяти и только проверяет, что вызов API подключен к потоку данных, и не отражает эффект реального файла.
- Результаты извлечения должны быть основаны на фактическом рендеринге PDF-ридера в качестве эталона приемки. Сложные ситуации, такие как сокрытие ОПГ, требуют проверки вручную.
Изображения, которые вы извлекаете из PDF-файлов, часто выглядят иначе, чем то, что вы видите на странице: они либо полностью черные, имеют неправильный размер, либо у них отсутствует фон или водяные знаки. Проблема обычно не в самом коде, а в том, что вы читаете исходный объект изображения внутри PDF-файла и пропускаете инструкции по композиции при рендеринге страницы.
Эта статья написана для разработчиков и обработчиков документов, которым необходимо использовать сценарии для анализа изображений PDF. Он подходит для таких сценариев, как предварительная обработка OCR и реорганизация контента. Прочитав, вы сможете понять разницу между исходным объектом и отображением страницы, узнать, почему SMask (мягкая маска) приводит к потере прозрачных областей, а также освоить набор методов самотестирования с использованием синтетических образцов.
В этой статье для демонстрации метода обработки используются синтетические образцы. Код проверен на примерах в изолированной среде и не является гарантией работоспособности всех реальных файлов или продукта. Перед обработкой важных документов, пожалуйста, сохраните оригиналы и просмотрите их по границам и пунктам приема в тексте.
Результаты извлечения изображений PDF не соответствуют странице? Вывод в одно предложение
Извлеченные байты основного изображения не соответствуют полному эффекту на странице. SMask должен обрабатываться одновременно, а фактический результат рендеринга считывателя используется в качестве эталона приемки.
| твоя ситуация | Рекомендуемые практики | причина |
|---|---|---|
| Результатом извлечения является прямоугольник сплошного цвета, а прозрачная область становится черной или белой. | Проверьте, равен ли smask_xref 0, и объедините SMask как альфа-канал с основным изображением. | Изображения с прозрачностью можно хранить отдельно как основное изображение и мягкую маску. Извлечение только основного изображения приведет к потере информации о прозрачности. |
| Извлекается полное большое изображение, и на странице отображается только его часть. | Считайте матрицу CTM и /BBox, обрежьте в соответствии с областью отображения. | Одну и ту же базовую карту можно повторно использовать на нескольких страницах, при этом каждая страница отображает только свою часть области. |
| Ориентация изображения перевернута или деформирована | Считайте параметры матрицы для геометрической коррекции и вручную проверьте текст и грани. | Матрица преобразования может содержать отрицательное масштабирование или неоднородные преобразования. |
| Извлечение прошло успешно, но страницу невозможно просмотреть. | Запросить статус OCG и сравнить с CropBox | Изображение может быть скрыто дополнительной группой контента или за пределами области обрезки. |
| Изображение размытое или низкое разрешение. | Зарегистрируйте метаданные DPI и отметьте их как низкое качество, при необходимости повторно отсканируйте исходные файлы. | Исходное встроенное изображение само по себе может представлять собой миниатюру с низким разрешением. |
Разница между исходными объектами и конвейерами рендеринга
PDF-файлы структурированы как хранилище ресурсов. `Document.extract_image(xref)` Этот метод позволяет забирать детали со склада в том виде, в котором они есть. Отображение на странице также должно пройти несколько процессов: масштабирование матрицы преобразования (CTM), обрезку контура (Clip Path), смешивание группы прозрачности (Transparency Group) и наложение мягкой маски (Soft Mask).
Наиболее типичное отличие связано с SMask. Многие PNG-файлы с каналом прозрачности внутри PDF-файла разделены на две части: поток изображений RGB и отдельный поток маски серого. Если вы извлекаете только основное изображение и отбрасываете связанный объект SMask, вы получите прямоугольник без прозрачности, а исходно прозрачная область станет черной или белой.
Кроме того, в целях экономии объема одна и та же базовая карта с высоким разрешением может повторно использоваться на нескольких страницах, и на каждой странице отображается только ее часть с помощью разных /BBox и матриц. Прямое извлечение приведет к получению полного большого изображения, а не обрезанных фрагментов, которые видит пользователь. Это «то, что вы видите, не то, что вы получаете» является неотъемлемой характеристикой PDF как формата обмена и не является недостатком библиотеки синтаксического анализа.
В таблице ниже сравниваются две точки зрения:
📊 Сравнение ядра
| Контрастные размеры | Извлеките исходный объект напрямую | Результаты рендеринга страницы |
|---|---|---|
| Получить контент | Оригинальные детали на складе ресурсов, например основной поток изображений | Визуальные эффекты после обработки инструкциями синтеза |
| прозрачность | Основное изображение и SMask могут храниться отдельно, и их необходимо связать вручную. | Мягкие маски накладываются, а прозрачные области отображаются нормально. |
| Размер и ассортимент | Может быть базовая карта в полном размере | Ограничено CTM, /BBox и контурами отсечения. |
| Ситуация повторного использования | Одна и та же базовая карта может использоваться несколькими страницами. | Каждая страница представляет только свою часть |
Синтетическая тестовая среда и обработка граничных случаев
Чтобы проверить логику извлечения, не полагаясь на внешние файлы, необходимо создать синтетический PDF-файл, содержащий SMask. Следующий код использует PyMuPDF для создания в памяти тестового документа, в котором объект изображения имеет независимую мягкую маску, имитирующую ситуацию в реальной сцене, где «значок имеет прозрачный фон, но нижележащий слой хранится в отдельном потоке».
from io import BytesIO
from PIL import Image
import pymupdf
im = Image.new("RGBA", (16, 16), (255, 0, 0, 128))
raw = BytesIO()
im.save(raw, format="PNG")
with pymupdf.open() as doc:
page = doc.new_page(width=100, height=100)
page.insert_image(pymupdf.Rect(10, 10, 70, 70), stream=raw.getvalue())
images = page.get_images(full=True)
assert len(images) == 1
xref, smask = images[0][:2]
assert xref > 0 and smask > 0
assert doc.extract_image(xref)["width"] == 16
assert doc.extract_image(smask)["image"]
Правильное ожидание вывода: программа должна уметь распознавать, что изображение связано с SMask, и успешно извлекать основные данные изображения.
Код полностью автономен и не требует каких-либо внешних входных файлов. Он синтезирует PDF-файл с помощью SMask в памяти, а затем проверяет, правильно ли логика извлечения распознает ассоциацию маски. Код содержит два ключевых утверждения: одно проверяет целостность извлеченных данных, а другое проверяет осведомленность о состоянии, связанном с SMask.
Этот код ориентирован на проверку целостности на уровне метаданных. В реальном производстве, если используется smask_xref != 0, необходимо использовать такие библиотеки, как Pillow, для вставки результата doc.extract_image(smask_xref) в основное изображение в качестве альфа-канала. Эти два утверждения охватывают два основных контракта: «данные могут быть извлечены» и «ассоциация маски видна» соответственно, что может предотвратить ложные успехи при пустых документах или изменениях API.
Границы принятия результатов извлечения и проверки вручную
Автоматизированное извлечение не может полностью заменить визуальное подтверждение. В следующей таблице приведены распространенные аномалии, стратегии реагирования и ситуации, которые следует оставить на усмотрение человека.
| Наблюдайте за явлениями | Возможные причины | Автоматизированные решения по обработке | Условия запуска проверки вручную |
|---|---|---|---|
| Изображение полностью черное или полностью белое. | SMask был извлечен как отдельный образ; декодирование цветового пространства не удалось | Проверьте ассоциацию SMask; попробуйте резервное цветовое пространство | После возврата контент по-прежнему не распознается; используются плашечные цвета или цвета, связанные с устройством |
| Ориентация изображения перевернута или растянута | Матрица CTM содержит отрицательное масштабирование или неравномерное преобразование. | Чтение параметров матрицы для геометрической коррекции | Текст или лица явно деформированы после коррекции; сложный векторный контур обрезки |
| Несколько маленьких фотографий объединены в одну большую картинку. | Узор плитки или полосатое хранилище | Разрезать или склеить по координатам BBox | Зазор в сращивании очевиден; по логике это должна быть самостоятельная смысловая единица |
| Извлечение прошло успешно, но страница не видна | Скрыто OCG (необязательная группа контента); вне посевной площади | Фильтр статуса запроса OCG; сравнить CropBox | Сложная логика уровней, такая как вложенная OCMD; динамические поля формы |
| Очень низкое разрешение или размытое изображение | Исходная вставка представляет собой миниатюру низкого разрешения. | Записывать метаданные DPI, отмечать как низкое качество | Ключевые изображения или текст нечитабельны из-за размытости; исходный документ необходимо повторно отсканировать. |
Следует отметить, что «демонстрация кода» лишь проверяет связность вызовов API и потоков данных и не означает, что сквозной эффект находится на должном уровне. При работе с вложенной логикой OCG, пользовательскими шейдерами или зашифрованными документами выходные данные сценария предназначены только для справки и должны приниматься при фактическом рендеринге программой чтения PDF.
🎯 Какой метод подходит вам?
Если вам нужно сохранить эффект прозрачности
Сначала проверьте, существует ли SMask, объедините его с альфа-каналом, а затем выполните последующую обработку.
Если вам нужна только часть изображения на странице
Прочтите CTM и /BBox и обрежьте их в соответствии с областью отображения вместо непосредственного сохранения базового изображения.
Если ваше изображение представляет собой отсканированное изображение или встроенное изображение низкого разрешения
Сначала запишите метаданные DPI и отметьте качество. Если содержание ключа неясно, вернитесь к исходному файлу и повторите сканирование.
Если документ содержит слои, шифрование или сложную обрезку
Рассматривайте выходные данные сценария как предварительный результат, и окончательный эффект рендеринга в программе чтения PDF-файлов будет иметь преимущественную силу.
❓ Часто задаваемые вопросы (FAQ)
1. Почему прозрачная область извлеченного изображения становится черной?
Общая причина заключается в том, что информация о прозрачности хранится в SMask, и извлекается только основное изображение без включения маски.
2. Извлеченное изображение намного больше того, что вы видите на странице. Что происходит?
Одна и та же базовая карта может повторно использоваться на нескольких страницах. На каждой странице отображается только часть ее через /BBox и матрицу. Прямое извлечение приведет к созданию полной базовой карты.
3. Код выполняется. Означает ли это, что извлеченные результаты можно использовать напрямую?
не могу. Демонстрация кода только проверяет связность вызовов API и потоков данных, а для окончательной приемки необходимо использовать фактические результаты рендеринга считывателя.
4. Извлечение прошло успешно, но изображение на странице не видно. В чем может быть причина?
Изображение может быть скрыто дополнительной группой контента (OCG) или за пределами области обрезки. Статус OCG можно запросить и сравнить с CropBox.
📝 Резюме
Исходный объект изображения в PDF и эффект отображения страницы — это два уровня вещей, и перед извлечением необходимо выяснить взаимосвязь между ними. Обработайте SMask, информацию о матрице и обрезке вместе и используйте результаты рендеринга для приемки, чтобы результаты были надежными.
Попробуйте сейчас: загрузите документ, чтобы начать перевод, сохранив исходный макет.


