Извлечь страницу из pdf в формате jpeg

100

В коде Python, как эффективно сохранить определенную страницу в формате PDF в виде файла JPEG? (Пример использования: у меня есть веб-сервер с флягой Python, на который будут загружены файлы PDF и сохранены файлы jpeg, соответствующие каждой странице.)

Это решение близко, но проблема в том, что оно не конвертирует всю страницу в jpeg.

вишвас васуки
источник
1
В зависимости от изображения, может быть лучше распаковать как png. Это применимо, если страница содержит в основном текст.
Пол Руни

Ответы:

133

Можно использовать библиотеку pdf2image.

Вы можете установить его, просто используя,

pip install pdf2image

После установки вы можете использовать следующий код для получения изображений.

from pdf2image import convert_from_path
pages = convert_from_path('pdf_file', 500)

Сохранение страниц в формате jpeg

for page in pages:
    page.save('out.jpg', 'JPEG')

Изменить: в репозитории Github pdf2image также упоминается, что он использует pdftoppmи требует других установок:

pdftoppm - это программа, которая творит чудеса. Он распространяется как часть большого пакета под названием poppler . Пользователи Windows должны будут установить poppler для Windows . Пользователи Mac должны будут установить poppler для Mac . У пользователей Linux будет предустановлен pdftoppm с дистрибутивом (протестировано на Ubuntu и Archlinux), если это не так, запустите sudo apt install poppler-utils.

Вы можете установить последнюю версию под Windows с помощью anaconda, выполнив следующие действия:

conda install -c conda-forge poppler

Примечание: версии Windows до 0,67 доступны по адресу http://blog.alivate.com.au/poppler-windows/, но обратите внимание, что версия 0,68 была выпущена в августе 2018 года, поэтому вы не получите новейшие функции или исправления ошибок.

Кеваль Дэйв
источник
4
Привет, poppler - это просто заархивированный файл, ничего не устанавливает, что делать с файлами dll или bin?
gaurwraith
@gaurwraith: воспользуйтесь следующей ссылкой на poppler . Почему-то ссылка в описании от Родриго не такая, как в репозитории на github.
Тобиас
1
@elPastor, вы можете добавить first_page и last_page в аргумент функции conver_from_path, чтобы преобразовать только указанную страницу
Кеваль Дэйв
1
@Jacob 500 - это dpi. Это компромисс между требуемым разрешением и доступными вычислениями. В моих экспериментах 500 работали хорошо в большинстве случаев, а 300 давали мне изображения с низким разрешением.
Кеваль Дэйв
1
Это работает для преобразования первой страницы PDF и ничего больше:from pdf2image import convert_from_path pages = convert_from_path('file.pdf', 500) pages = convert_from_path('file.pdf', 500, single_file=True) pages[0].save('file.jpg', 'JPEG')
helgis
38

Я нашел это простое решение, PyMuPDF , вывод в файл png. Обратите внимание, что библиотека импортируется как «fitz» - историческое название используемого механизма рендеринга.

import fitz

pdffile = "infile.pdf"
doc = fitz.open(pdffile)
page = doc.loadPage(0)  # number of page
pix = page.getPixmap()
output = "outfile.png"
pix.writePNG(output)
JJPty
источник
1
Пожалуйста, добавьте пояснение к своему ответу.
Shanteshwar Inde
1
Хорошая библиотека и без проблем устанавливается на Windows 10 (колеса не требуются). github.com/pymupdf
Товарищ Че
7
Это ЛУЧШИЙ ответ. Это был единственный код, который не требовал дополнительной установки на мою ОС. Скрипты Python должны быть ориентированы на работу в системе Python. Мне не нужно было устанавливать poppler, pdftoppm, imageMagick или ghostscript и т. Д. (Python 3.6)
ZStoneDPM
1
На самом деле для этого требуется другая установка (библиотека fitz, импортированная без ссылки и ее зависимости), этот ответ является неполным (как и все ответы на этот вопрос)
Томмазо Геррини
1
@JJPty Можно вместо pdf файла, взятого из пути, взять из pdfurl? Кроме того, может ли файл png быть данными в потоке, а не файлом output-png?
Шубхам Агравал,
18

Библиотека Python pdf2image(используется в другом ответе) на самом деле не делает гораздо больше , чем просто запуск pdttoppm с subprocess.Popen, так вот короткая версия делает это непосредственно:

PDFTOPPMPATH = r"D:\Documents\software\____PORTABLE\poppler-0.51\bin\pdftoppm.exe"
PDFFILE = "SKM_28718052212190.pdf"

import subprocess
subprocess.Popen('"%s" -png "%s" out' % (PDFTOPPMPATH, PDFFILE))

Вот ссылка для установки Windows pdftoppm(содержится в пакете poppler): http://blog.alivate.com.au/poppler-windows/

Basj
источник
4
Привет, ссылка для установки pdftoppm в Windows - это просто набор заархивированных файлов, что вы должны с ними делать, чтобы они работали? Благодарность!
gaurwraith
14

Устанавливать Poppler на вашу ОС не нужно. Это будет работать:

pip install Wand

from wand.image import Image

f = "somefile.pdf"
with(Image(filename=f, resolution=120)) as source: 
    for i, image in enumerate(source.sequence):
        newfilename = f[:-4] + str(i + 1) + '.jpeg'
        Image(image).save(filename=newfilename)
DevB2F
источник
12
Для работы с палочкой необходимо установить библиотеку ImageMagick .
Neeraj Gulia
3
Я пробовал это, и мне также нужно было установить Ghostscript (с использованием Windows 10 и Python 3.7). Сделал это, и он работал отлично.
jcf 01
1
что за f [: - 4]? о нем больше нигде не упоминается
Ари,
@Ari f [: - 4] будет вырезать ".pdf" из имени файла (разрезание строки), чтобы создать новое имя файла с другим расширением.
Fabian
10

@gaurwraith, установите poppler для Windows и используйте pdftoppm.exe следующим образом:

  1. Загрузите zip-файл с последними двоичными файлами / библиотеками Poppler с http://blog.alivate.com.au/poppler-windows/ и распакуйте в новую папку в папке с файлами программы. Например: «C: \ Program Files (x86) \ Poppler».

  2. Добавьте «C: \ Program Files (x86) \ Poppler \ poppler-0.68.0 \ bin» в переменную среды SYSTEM PATH.

  3. Из строки cmd установите модуль pdf2image -> «pip install pdf2image».

  4. Или, в качестве альтернативы, напрямую выполните pdftoppm.exe из вашего кода, используя модуль подпроцесса Python, как объяснил пользователь Basj.

@vishv Как vAsuki, этот код должен сгенерировать нужные вам файлы jpgs через модуль подпроцесса для всех страниц одного или нескольких файлов PDF в заданной папке:

import os, subprocess

pdf_dir = r"C:\yourPDFfolder"
os.chdir(pdf_dir)

pdftoppm_path = r"C:\Program Files (x86)\Poppler\poppler-0.68.0\bin\pdftoppm.exe"

for pdf_file in os.listdir(pdf_dir):

    if pdf_file.endswith(".pdf"):

        subprocess.Popen('"%s" -jpeg %s out' % (pdftoppm_path, pdf_file))

Или с помощью модуля pdf2image:

import os
from pdf2image import convert_from_path

pdf_dir = r"C:\yourPDFfolder"
os.chdir(pdf_dir)

    for pdf_file in os.listdir(pdf_dir):

        if pdf_file.endswith(".pdf"):

            pages = convert_from_path(pdf_file, 300)
            pdf_file = pdf_file[:-4]

            for page in pages:

               page.save("%s-page%d.jpg" % (pdf_file,pages.index(page)), "JPEG")
photek1944
источник
Это очень помогло. Благодарность!
Sreekiran
1
На самом деле это должен быть принятый ответ. Показывает, что делать с установленными двоичными файлами для Poppler
Kunj Mehta
3

Это утилита под названием pdftojpg, которую можно использовать для преобразования pdf в img.

Вы можете найти код здесь https://github.com/pankajr141/pdf2jpg

from pdf2jpg import pdf2jpg
inputpath = r"D:\inputdir\pdf1.pdf"
outputpath = r"D:\outputdir"
# To convert single page
result = pdf2jpg.convert_pdf2jpg(inputpath, outputpath, pages="1")
print(result)

# To convert multiple pages
result = pdf2jpg.convert_pdf2jpg(inputpath, outputpath, pages="1,0,3")
print(result)

# to convert all pages
result = pdf2jpg.convert_pdf2jpg(inputpath, outputpath, pages="ALL")
print(result)
утка
источник
2
эта java вещь просто удалила всю мою папку, полную pdf, манипулирующую скриптами python ....?
Ulf Gjerdingen
2

GhostScript работает намного быстрее, чем Poppler для системы на базе Linux.

Ниже приведен код для преобразования PDF в изображение.

def get_image_page(pdf_file, out_file, page_num):
    page = str(page_num + 1)
    command = ["gs", "-q", "-dNOPAUSE", "-dBATCH", "-sDEVICE=png16m", "-r" + str(RESOLUTION), "-dPDFFitPage",
               "-sOutputFile=" + out_file, "-dFirstPage=" + page, "-dLastPage=" + page,
               pdf_file]
    f_null = open(os.devnull, 'w')
    subprocess.call(command, stdout=f_null, stderr=subprocess.STDOUT)

GhostScript можно установить на macOS с помощью brew install ghostscript

Информацию по установке для других платформ можно найти здесь . Если он еще не установлен в вашей системе.

Кеваль Дэйв
источник
0

Я использую (возможно) гораздо более простой вариант pdf2image:

cd $dir
for f in *.pdf
do
  if [ -f "${f}" ]; then
    n=$(echo "$f" | cut -f1 -d'.')
    pdftoppm -scale-to 1440 -png $f $conv/$n
    rm $f
    mv  $conv/*.png $dir
  fi
done

Это небольшая часть сценария bash в цикле для использования узкого устройства приведения типов. Проверяет каждые 5 секунд добавленные файлы PDF (все) и обрабатывает их. Это для демонстрационного устройства, в конечном итоге преобразование будет выполняться на удаленном сервере. Преобразование в .PNG сейчас, но .JPG тоже возможно.

Это преобразование, вместе с переходами в формате A4, отображением видео, двух плавно прокручиваемых текстов и логотипа (с переходом в трех версиях) устанавливает Pi3 на все 4x 100% загрузки процессора ;-)

Роберт
источник
0
from pdf2image import convert_from_path
import glob

pdf_dir = glob.glob(r'G:\personal\pdf\*')  #your pdf folder path
img_dir = "G:\\personal\\img\\"           #your dest img path

for pdf_ in pdf_dir:
    pages = convert_from_path(pdf_, 500)
    for page in pages:
        page.save(img_dir+pdf_.split("\\")[-1][:-3]+"jpg", 'JPEG')
Сайпрасад Бхатвадекар
источник
Было бы лучше, если бы вы объяснили, как предоставленный вами код отвечает на вопрос.
pppery
2
@pppery Python довольно удобочитаем, в комментариях указываются исходная папка и выходная папка, остальное читается как английский.
Ари
-1

Вот решение, которое не требует дополнительных библиотек и работает очень быстро. Это было найдено по адресу : https://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html# Я добавил код в функцию, чтобы сделать ее более удобной.

def convert(filepath):
    with open(filepath, "rb") as file:
        pdf = file.read()

    startmark = b"\xff\xd8"
    startfix = 0
    endmark = b"\xff\xd9"
    endfix = 2
    i = 0

    njpg = 0
    while True:
        istream = pdf.find(b"stream", i)
        if istream < 0:
            break
        istart = pdf.find(startmark, istream, istream + 20)
        if istart < 0:
            i = istream + 20
            continue
        iend = pdf.find(b"endstream", istart)
        if iend < 0:
            raise Exception("Didn't find end of stream!")
        iend = pdf.find(endmark, iend - 20)
        if iend < 0:
            raise Exception("Didn't find end of JPG!")

        istart += startfix
        iend += endfix
        jpg = pdf[istart:iend]
        newfile = "{}jpg".format(filepath[:-3])
        with open(newfile, "wb") as jpgfile:
            jpgfile.write(jpg)

        njpg += 1
        i = iend

        return newfile

Вызовите convert с путем pdf в качестве аргумента, и функция создаст файл .jpg в том же каталоге.

moo5e
источник
1
Этот метод выглядит так, как будто он извлекает изображения, которые были встроены в файл, а не растеризует страницу файла как изображение, что и хотел вопрошающий.
Джош Галлахер,