Чому зображення, взяті з PDF-файлу, відрізняються від зображених на сторінці?

Зображення з прозорістю можна зберігати окремо як основне зображення та програмну маску. Далі за допомогою Pillow створіть RGBA PNG, вставте PDF-файл у пам’яті та перегляньте основне зображення та SMask. Вилучення байтів основного зображення не означає отримання повного ефекту прозорості, а також реконструкцію всіх екземплярів відображення на сторінці.

Зображення, які ви витягуєте з 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Розрив зварювання очевидний; за логікою це має бути самостійна семантична одиниця
Видобуток успішний, але сторінка не відображаєтьсяHidden by 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, матрицю та інформацію про кадрування разом і використовуйте результати візуалізації для прийняття, щоб результати були надійними.

Спробуйте зараз: завантажте документ, щоб розпочати переклад, зберігаючи вихідний макет

Оновлено 2026-11-13