Извлекать изображения из PDF без передискретизации в python? - PullRequest
53 голосов
/ 22 апреля 2010

Как можно извлечь все изображения из PDF-документа в собственном разрешении и формате?(Имеется в виду извлечь tiff как tiff, jpeg как jpeg и т. Д. И без повторной выборки).Макет не важен, мне все равно, где находится исходное изображение на странице.

Я использую Python 2.7, но при необходимости могу использовать 3.x.

Ответы [ 13 ]

2 голосов
/ 06 февраля 2019

По состоянию на февраль 2019 года решение, данное @sylvain (по крайней мере, в моей настройке), не работает без небольшой модификации: xObject[obj]['/Filter'] не значение, а список, таким образом, чтобы скрипт работал, Мне пришлось изменить проверку формата следующим образом:

import PyPDF2, traceback

from PIL import Image

input1 = PyPDF2.PdfFileReader(open(src, "rb"))
nPages = input1.getNumPages()
print nPages

for i in range(nPages) :
    print i
    page0 = input1.getPage(i)
    try :
        xObject = page0['/Resources']['/XObject'].getObject()
    except : xObject = []

    for obj in xObject:
        if xObject[obj]['/Subtype'] == '/Image':
            size = (xObject[obj]['/Width'], xObject[obj]['/Height'])
            data = xObject[obj].getData()
            try :
                if xObject[obj]['/ColorSpace'] == '/DeviceRGB':
                    mode = "RGB"
                elif xObject[obj]['/ColorSpace'] == '/DeviceCMYK':
                    mode = "CMYK"
                    # will cause errors when saving
                else:
                    mode = "P"

                fn = 'p%03d-%s' % (i + 1, obj[1:])
                print '\t', fn
                if '/FlateDecode' in xObject[obj]['/Filter'] :
                    img = Image.frombytes(mode, size, data)
                    img.save(fn + ".png")
                elif '/DCTDecode' in xObject[obj]['/Filter']:
                    img = open(fn + ".jpg", "wb")
                    img.write(data)
                    img.close()
                elif '/JPXDecode' in xObject[obj]['/Filter'] :
                    img = open(fn + ".jp2", "wb")
                    img.write(data)
                    img.close()
                elif '/LZWDecode' in xObject[obj]['/Filter'] :
                    img = open(fn + ".tif", "wb")
                    img.write(data)
                    img.close()
                else :
                    print 'Unknown format:', xObject[obj]['/Filter']
            except :
                traceback.print_exc()
2 голосов
/ 08 августа 2018

Вы также можете использовать команду pdfimages в Ubuntu.

Установите poppler lib с помощью следующих команд.

sudo apt install poppler-utils

sudo apt-get install python-poppler

pdfimages file.pdf image

Список созданных файлов (например, в формате PDF есть два изображения)

image-000.png
image-001.png

Это работает! Теперь вы можете использовать subprocess.run для запуска этого из python.

1 голос
/ 23 марта 2016

Я добавил все это вместе в PyPDFTK здесь .

Мой собственный вклад - обработка /Indexed файлов как таковых:

for obj in xObject:
    if xObject[obj]['/Subtype'] == '/Image':
        size = (xObject[obj]['/Width'], xObject[obj]['/Height'])
        color_space = xObject[obj]['/ColorSpace']
        if isinstance(color_space, pdf.generic.ArrayObject) and color_space[0] == '/Indexed':
            color_space, base, hival, lookup = [v.getObject() for v in color_space] # pg 262
        mode = img_modes[color_space]

        if xObject[obj]['/Filter'] == '/FlateDecode':
            data = xObject[obj].getData()
            img = Image.frombytes(mode, size, data)
            if color_space == '/Indexed':
                img.putpalette(lookup.getData())
                img = img.convert('RGB')
            img.save("{}{:04}.png".format(filename_prefix, i))

Обратите внимание, что когда найдены /Indexed файлы, вы не можете просто сравнить /ColorSpace со строкой, потому что она выглядит как ArrayObject. Итак, мы должны проверить массив и получить индексированную палитру (lookup в коде) и установить его в объекте PIL Image, в противном случае он остается неинициализированным (ноль), и все изображение отображается черным.

Моим первым инстинктом было сохранение их в формате GIF (что является индексированным форматом), но мои тесты показали, что PNG были меньше и выглядели одинаково.

Я нашел эти типы изображений при печати в PDF на Foxit Reader PDF Printer.

...