Допустим, у вас есть страница в формате PDF с различными сложными элементами внутри. Цель состоит в том, чтобы обрезать область страницы (чтобы извлечь только один из элементов), а затем вставить ее на другую страницу PDF.
Вот упрощенная версия моего кода:
import PyPDF2
import PyPdf
def extract_tree(in_file, out_file):
with open(in_file, 'rb') as infp:
# Read the document that contains the tree (in its first page)
reader = pyPdf.PdfFileReader(infp)
page = reader.getPage(0)
# Crop the tree. Coordinates below are only referential
page.cropBox.lowerLeft = [100,200]
page.cropBox.upperRight = [250,300]
# Create an empty document and add a single page containing only the cropped page
writer = pyPdf.PdfFileWriter()
writer.addPage(page)
with open(out_file, 'wb') as outfp:
writer.write(outfp)
def insert_tree_into_page(tree_document, text_document):
# Load the first page of the document containing 'text text text text...'
text_page = PyPDF2.PdfFileReader(file(text_document,'rb')).getPage(0)
# Load the previously cropped tree (cropped using 'extract_tree')
tree_page = PyPDF2.PdfFileReader(file(tree_document,'rb')).getPage(0)
# Overlay the text-page and the tree-crop
text_page.mergeScaledTranslatedPage(page2=tree_page,scale='1.0',tx='100',ty='200')
# Save the result into a new empty document
output = PyPDF2.PdfFileWriter()
output.addPage(text_page)
outputStream = file('merged_document.pdf','wb')
output.write(outputStream)
# First, crop the tree and save it into cropped_document.pdf
extract_tree('document1.pdf', 'cropped_document.pdf')
# Now merge document2.pdf with cropped_document.pdf
insert_tree_into_page('cropped_document.pdf', 'document2.pdf')
Метод "extract_tree", кажется, работает. Он генерирует файл PDF, содержащий только обрезанную область (в примере дерево). Проблема в том, что когда я пытаюсь вставить дерево в новую страницу, то звезда и дом исходного изображения все равно вклеиваются
Привет, Эдеки... Код, который я разместил, является упрощенной версией моего кода. Я реализовал интерфейс для определения границ урожая, но в приведенном выше коде я жестко закодировал некоторые случайные значения в качестве ссылки. Я почти уверен, что проблема не в границах, потому что файл "cropped_document.pdf" кажется идеально обрезанным, но когда я пытаюсь объединить его с целевой страницей, обрезка игнорируется и вставляется вся страница (вместо только обрезать). Я предполагаю, что, может быть, я неправильно понимаю цель урожая Box
Попробуйте сохранить само обрезанное изображение и не использовать писатель.addPage(страница). Похоже, что этот метод добавляет страницу в существующий PDF-файл, но вы все еще вызываете страницу 1 PDF-файла в функции insert_tree. Но обрезанное изображение находится на второй странице из-за этого метода, поэтому оно также объединит дом и звезду.
В качестве примера я использовал исследовательскую работу, содержащую график (пример: arxiv.org/pdf/1807.03819.pdf). Я обрезал график, а затем попытался наложить его в произвольном месте первой страницы.
Внес правку в свой предыдущий комментарий. Обрезанное изображение находится на странице 1 или странице 2 файлаcropped_document.pdf? Я думаю, что проблема может заключаться в использовании write.addPage(page) и выполнении слияния на первой странице документа с помощью getPage(0).
В моем примере кода я предполагаю, что все файлы PDF имеют только одну страницу. Writer.addPage(page) добавляет страницу в новый пустой документ, поэтому у него будет только одна страница. Как сохранить само обрезанное изображение без write.addPage(page)?
Позвольте мне сначала попытаться воссоздать проблему, используя некоторые тестовые документы. Я думаю, что вижу проблему.
Спасибо Эдеки. Я добавил дополнительные комментарии к коду, чтобы сделать его более понятным
Давайте продолжить обсуждение в чате.
Просто на случай, если это кому-то поможет: в итоге я обрезал области PDF, затем преобразовал в формат SVG, затем обратно в PDF и, наконец, объединил. Это решило мою проблему. Я предполагаю, что в этом случае pypdf2 редактирует только метаданные страницы, а не фактическое содержимое, поэтому нежелательные области сохраняются и снова появляются при окончательном слиянии. Вместо этого SVG сохраняет только нужный регион и отбрасывает остальные. Единственное неудобство в том, что текст больше не редактируется, так как он будет преобразован в векторные рисунки, но в моем случае это не было проблемой.






Я попробовал кое-что, что действительно сработало. Попробуйте преобразовать свой первый вывод (pdf, содержащий только дерево) в docx, а затем преобразовать его еще раз из docx в pdf, прежде чем объединять его с другими страницами pdf. Это будет работать (только дерево будет объединено).
Разрешите спросить, как вы реализовали интерфейс, определяющий границы кропа Au.
У меня была точно такая же проблема. В конце концов, решение для меня состояло в том, чтобы внести небольшую правку в исходный код pyPDF2 (из этот пул реквест, который так и не попал в основную ветку). Что вам нужно сделать, так это вставить эти строки в метод _mergePage класса PageObject внутри файла pdf.py:
page2Content = ContentStream(page2Content, self.pdf)
page2Content.operations.insert(0, [map(FloatObject, [page2.trimBox.getLowerLeft_x(), page2.trimBox.getLowerLeft_y(), page2.trimBox.getWidth(), page2.trimBox.getHeight()]), "re"])
page2Content.operations.insert(1, [[], "W"])
page2Content.operations.insert(2, [[], "n"])
(см. запрос на включение, где именно их разместить). После этого вы можете обрезать нужный раздел PDF-файла и без проблем объединить его с другой страницей. Нет необходимости сохранять обрезанный фрагмент в отдельный PDF-файл, если вы этого не хотите.
from PyPDF2 import PdfFileReader, PdfFileWriter
tree_page = PdfFileReader(open('document1.pdf','rb')).getPage(0)
text_page = PdfFileReader(open('document2.pdf','rb')).getPage(0)
tree_page.cropBox.lowerLeft = [100,200]
tree_page.cropBox.upperRight = [250, 300]
text_page.mergeScaledTranslatedPage(page2=tree_page, scale='1.0', tx='100', ty='200')
output = PdfFileWriter()
output.addPage(text_page)
output.write(open('merged_document.pdf', 'wb'))
Возможно, есть лучший способ сделать это, вставив этот код без непосредственного редактирования исходного кода. Я был бы признателен, если бы кто-нибудь нашел способ сделать это, поскольку это, по общему признанию, немного хитрый взлом.
Как вы определили границы обрезки деревьев? Любые примеры PDF-файлов, на которые вы можете указать? Я предполагаю, что кадрирование все еще захватывает эти изображения.