PDF виглядає горизонтально, але витягнуті координати неправильні: чітко поясніть матрицю обертання
Проаналізуйте проблему розсувності координат повернутих сторінок PDF і детально поясніть перетворення матриці між неповерненим простором і простором відображення в PyMuPDF. Надає приклади синтезу в пам’яті та контрольні списки прийняття, щоб пояснити, як використовувати OmniDoc для оцінки складних ефектів відновлення макета в процесі перекладу документів.
Коли я обробляв PDF, я чітко бачив, що таблиця була в правій частині сторінки, але витягнуті координати вказували на верхній лівий кут, або виділений кольоровий блок опускався на позицію заголовка. Цей тип проблеми часто є не помилкою в бібліотеці аналізу, а невідповідністю між системою координат PDF-файлу та візуальним відтворенням. Ця стаття призначена для розробників, які потребують позиціонування тексту, зіставлення областей або створення анотацій. У ньому пояснюється, як атрибут /Rotate викликає розбіжність координат, і для завершення перетворення використовується матриця обертання PyMuPDF.
Усі приклади в цій статті синтезовано в пам’яті, і реальні файли не читаються. Перед обробкою важливих документів збережіть оригінали, а потім перегляньте їх один за одним відповідно до меж і пунктів прийняття в документі.
Що робити, якщо координати PDF не збігаються після повороту? Висновок одним реченням
Використовуйте Page.rotation_matrix для перетворення неповернених координат на відображувані координати та перевіряйте page.rotation сторінка за сторінкою перед обробкою. Не припускайте, що напрямки координат усіх сторінок узгоджені.
| ваша ситуація | Рекомендовані практики | причина |
|---|---|---|
| Витягнуті текстові координати не відповідають візуальному положенню | Помножте координати на Page.rotation_matrix перед початком графіка | За замовчуванням текстові координати повертаються відносно неповернутої сторінки. |
| Необхідно повернути позицію клацання до початкових координат | Використовуйте Page.derotation_matrix для зворотного перетворення | Ця матриця виконує зворотне перетворення від відображених координат до неповернутих координат |
| Габаритне зміщення фіксованої відстані | Перевірте CropBox і MediaBox, компенсуйте за допомогою page.cropbox_position | Невідповідність між двома джерелами призведе до фіксованого зміщення |
| В одному документі сторінки повертаються під різними кутами | Читайте page.rotation сторінка за сторінкою, не мультиплексуйте матрицю глобально | Статус обертання різних сторінок може відрізнятися |
| Складний макет (змішані кілька стовпців і частково повернуті діаграми) | Призупиніть автоматичний процес і перейдіть до ручного оцінювання | Автоматична перевірка на таких сторінках може не працювати |
Зрозумійте різницю між неповернутим простором і відображеним простором
Сторінки PDF можуть містити атрибут /Rotate зі значеннями 0, 90, 180 або 270 градусів. Це обертання автоматично застосовується під час візуалізації читача, але координати потоку вмісту сторінки все ще базуються на неповернутому оригінальному MediaBox. Якщо ви безпосередньо використовуєте витягнуті вихідні координати для малювання або зіставлення площ, результати будуть зміщені.
PyMuPDF чітко розрізняє ці дві системи координат, починаючи з версії 1.17.0:
- Неповернутий простір: координати
Page.get_text(),Page.get_image_bbox()і всіх об’єктів анотації повертаються відносно неповернутої сторінки за умовчанням. - Дисплейний простір: лише
Page.rectіPage.bound()відображатимуть фактичний розмір дисплея після повороту.
Ця конструкція забезпечує стабільне вилучення вмісту. Навіть якщо кут повороту сторінки змінено, координати вилучення того самого тексту не зміняться. Але коли вам потрібно намалювати координати назад на сторінку або вирівняти їх за допомогою візуальних взаємодій, таких як клацання миші, ви повинні виконати перетворення координат вручну.
PyMuPDF надає дві ключові матриці:
Page.rotation_matrix: Перетворення неповернутих координат на відображення координат.Page.derotation_matrix: Виконайте зворотну операцію.
Ці дві матриці інкапсулюють перетворення трансляції та обертання, тому розробникам не потрібно писати обчислення тригонометричних функцій вручну.
Приклад синтезу: правильні та неправильні очікування перетворення координат
Щоб продемонструвати цей механізм, ми створюємо синтетичну сцену виключно в пам’яті, яка не покладається на зовнішні файли. Якщо вам потрібно протестувати справжній документ, заздалегідь підготуйте PDF-файл із атрибутом /Rotate=90 і переконайтеся, що його CropBox узгоджується з MediaBox, щоб усунути перешкоди зміщення кадрування.
Параметри введення: створіть книжкову сторінку формату A4 (595 x 842 pt), установіть /Rotate = 90. У неповернутому просторі точка (100, 100) розташована біля верхнього лівого кута; при повороті на 90 градусів візуальне положення точки істотно змінюється, оскільки система координат обертається разом з нею.
Очікується правильний результат: помножте (100, 100) на rotation_matrix, і отримані координати відображення повинні входити в дійсні межі повернутої сторінки (тобто page.rect). Для сторінки формату A4 за замовчуванням, повернутої на 90 градусів проти годинникової стрілки, вихідна точка верхнього лівого кута має бути розташована біля нижнього лівого кута простору відображення, тобто координата x більша, а координата y близька до 0. Конкретне значення залежить від визначення джерела MediaBox. Не просто припускайте, що y більше за x.
Обробка граничного випадку: коли кут повороту дорівнює 0, rotation_matrix має бути матрицею ідентичності. Якщо передано значення обертання, яке не є кратним 90 градусам, PyMuPDF зазвичай нормалізує його, але все одно рекомендується перевіряти валідність матриці, щоб уникнути генерації координат NaN.
Python реалізує логіку перевірки координат
У наступному прикладі показано, як перевірити перетворення координат у пам’яті. Він лише демонструє логіку роботи матриці і не є повним конвеєром обробки PDF. Переконайтеся, що PyMuPDF встановлено перед запуском, і виконайте його в середовищі, де у вас є заблоковані залежності.
import fitz # PyMuPDF
def validate_rotation_transform():
"""合成示例:验证旋转矩阵在未旋转坐标与显示坐标间的转换"""
doc = fitz.open() # 空文档,无需文件路径
page = doc.new_page(width=595, height=842)
# 设置页面旋转90度,模拟横向显示的PDF
page.set_rotation(90)
# 定义一个在未旋转空间中的测试点 (左上角附近)
unrotated_point = fitz.Point(100, 100)
# 获取旋转矩阵并执行变换
mat = page.rotation_matrix
display_point = unrotated_point * mat
# 验证1: 变换后的点必须位于旋转后的页面可视区域内
assert page.rect.contains(display_point), (
f"变换后坐标 {display_point} 超出显示边界 {page.rect}"
)
# 验证2: 对于默认A4逆时针旋转90度,原(100,100)应变为左下角
# 即 x 接近页宽(842),y 接近 0。注意:此处纠正了常见的 y>x 误区
assert display_point.x > 500 and display_point.y < 200, (
f"90度旋转预期左下角,实际得到 ({display_point.x:.1f}, {display_point.y:.1f})"
)
# 验证3: 逆变换可精确恢复原始坐标
inv_mat = page.derotation_matrix
recovered = display_point * inv_mat
assert abs(recovered.x - unrotated_point.x) < 0.01
assert abs(recovered.y - unrotated_point.y) < 0.01
doc.close()
print("坐标变换逻辑校验通过(合成数据)")
# 请在本地环境运行,不要假设线上环境已安装fitz
validate_rotation_transform()
Цей код не читає жодного реального файлу, але створює стан сторінки в пам'яті. Заява assert перевіряє раціональність математичної залежності, а не бізнес-коректність. Може знадобитися додаткове налагодження, якщо фактичний PDF містить нестандартні MediaBox або вкладені перетворення.
📊 Основне порівняння
| Порівняльний пункт | неповернутий простір | дисплейний простір |
|---|---|---|
| Типові джерела | get_text(), get_image_bbox(), анотаційні координати | Page.rect,Page.bound() |
| координатна дата | Ширина та висота оригінального MediaBox | Фактичний розмір дисплея після повороту |
| Загальне використання | Вилучення вмісту, ведення журналу стабільної зони | Намалюйте анотації та вирівняйте їх відповідно до позиції клацання |
| Метод перетворення | Помножте на rotation_matrix | Помножте на derotation_matrix, щоб відновити |
Критерії прийняття та межі перевірки вручну
Те, що код може передати твердження, не означає, що виробниче середовище надійне. У наведеній нижче таблиці наведено загальні винятки та рішення щодо їх обробки, щоб допомогти розрізнити сценарії, які можна автоматизувати та потребують ручного втручання.
| Спостерігайте за явищами | Можливі причини | обробка рішення |
|---|---|---|
| Габаритне зміщення фіксованої відстані | Походження CropBox і MediaBox несумісні | Використовуйте page.cropbox_position для компенсації зсуву |
| Після повороту координати тексту нормальні, але зображення зміщено. | Зображення використовує незалежну матрицю перетворення CTM | Використовуйте get_image_rects() замість get_image_bbox() |
| Деякі сторінки повернуто правильно, а деякі – неправильно. | Документ змішує сторінки з різними кутами повороту | Перевірте page.rotation сторінка за сторінкою, вимкніть матрицю глобального кешу |
| Після трансформації координати виходять за межі сторінки. | Сам оригінальний вміст обрізаний або має негативні координати | Позначте сторінку як ненормальну та перейдіть до перевірки вручну |
| Сторінка 0 градусів не потребує трансформації, але все одно має відхилення | Приховані метадані обертання, написані сторонніми інструментами | Примусовий виклик remove_rotation() для скидання та обробки |
Ця таблиця розглядає лише логіку перетворення координат і не охоплює точність OCR або проблеми кодування шрифту. У випадку складної верстки автоматична перевірка може не працювати. У цей час конвеєр слід призупинити та вручну вирішити, чи продовжувати.
Використовуйте контрольні списки для перекладу документів
Перед перекладом підтвердьте порядок сторінок, розташування джерела та цілісність тексту, а потім надішліть той самий десенсибілізований зразок для процесу перекладу. Після перекладу все одно потрібно перевірити, чи коректно відповідають заголовок, текст та ілюстрації, а не тільки, чи гладкий переклад.
OmniDoc (портал продуктів) надає багатоформатний портал перекладу документів, а на офіційному веб-сайті представлені функції OCR, глосарій і двомовне порівняння. Для команд, які хочуть працювати безпосередньо з файлами, це шлях, який варто оцінити на прикладах із реального життя. Будь ласка, використовуйте десенсибілізовані файли, на завантаження яких у вас є дозвіл, і скористайтеся прапорцями в цій статті, щоб переглянути результати. Немає жодних заяв про те, що OmniDoc використовує бібліотеки з відкритим кодом або внутрішні алгоритми, згадані в цій статті, і цей приклад не замінює тестування продуктивності продукту.
Додаткова інформація:
🎯 Який спосіб вам підходить?
Якщо вам потрібно намалювати витягнуті текстові координати назад на сторінку
Спочатку використовуйте rotation_matrix, щоб перетворити на відображення координат, а потім намалюйте виділення або анотації.
Якщо вам потрібно повернути клацання миші до вихідного вмісту
Використовуйте derotation_matrix для зворотного перетворення та перевірте, чи входить точка в допустимий діапазон відносно page.rect.
Якщо ви маєте справу з документами зі змішаними кутами повороту
Читайте page.rotation сторінка за сторінкою, не використовуйте повторно глобальну матрицю та позначайте сторінки поза межами.
Якщо ваша сторінка містить складні макети або частково повернуті діаграми
Спочатку перевірте синтетичні зразки та невеликі реальні зразки, а потім вирішіть, чи передавати їх автоматичному процесу. У разі виявлення аномалій передайте їх на перевірку вручну.
❓ Часті запитання (FAQ)
1. Чому координати, які повертає get_text(), не відповідають візуальному положенню?
Оскільки ці API повертаються відносно неповернутої сторінки за замовчуванням, атрибут /Rotate застосовується під час візуалізації читача.
2. Чи однакові датуми координат Page.rect і get_text()?
ні те саме. Page.rect і Page.bound() відображають повернутий розмір відображення, тоді як координати API, таких як get_text(), прив’язані до вихідної неповерненої ширини та висоти.
3. Чи потрібне перетворення, коли кут повороту дорівнює 0?
непотрібний. На цьому етапі rotation_matrix має бути матрицею ідентичності, але все одно рекомендується перевіряти упередженість, оскільки сторонні інструменти можуть записувати приховані метадані обертання.
4. Чи можна використовувати код безпосередньо для виробництва після передачі твердження?
Не рекомендується. Твердження лише перевіряє раціональність математичних співвідношень. Фактичний PDF-файл може мати нестандартний MediaBox, незалежне перетворення CTM або нестандартні сторінки, які все одно потребують перегляду елемент за елементом відповідно до форми прийняття.
📝 Підсумок
Джерело розбіжності координат полягає в різниці між неповерненим простором і простором відображення. Використовуючи rotation_matrix і derotation_matrix для перетворення в поєднанні з посторінковою перевіркою та переглядом вручну, ризик можна контролювати в діапазоні, який можна перевірити.
Спробуйте зараз: завантажте документ, щоб розпочати переклад, зберігаючи вихідний макет


