Extrahieren Sie eine Seite aus einem PDF als JPEG


95

Wie kann man im Python-Code eine bestimmte Seite in einem PDF effizient als JPEG-Datei speichern? (Anwendungsfall: Ich habe einen Python-Flask-Webserver, auf dem PDF-Dateien hochgeladen werden und JPEG-Dateien, die jeder Seite entsprechen, gespeichert werden.)

Diese Lösung ist nah, aber das Problem ist, dass nicht die gesamte Seite in JPEG konvertiert wird.


1
Je nach Bild ist es möglicherweise besser, als PNG zu extrahieren. Dies gilt, wenn die Seite hauptsächlich Text enthält.
Paul Rooney

Antworten:


124

Die pdf2image-Bibliothek kann verwendet werden.

Sie können es einfach installieren mit,

pip install pdf2image

Nach der Installation können Sie den folgenden Code verwenden, um Bilder abzurufen.

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

Speichern von Seiten im JPEG-Format

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

Bearbeiten: Das Github-Repo pdf2image erwähnt auch, dass es verwendet pdftoppmund andere Installationen erfordert:

pdftoppm ist die Software, die die eigentliche Magie ausübt. Es wird als Teil eines größeren Pakets namens Poppler verteilt . Windows-Benutzer müssen Poppler für Windows installieren . Mac-Benutzer müssen Poppler für Mac installieren . Linux-Benutzer haben pdftoppm mit der Distribution vorinstalliert (getestet unter Ubuntu und Archlinux), wenn dies nicht der Fall ist sudo apt install poppler-utils.

Sie können die neueste Version unter Windows mit anaconda installieren, indem Sie Folgendes tun:

conda install -c conda-forge poppler

Hinweis: Windows-Versionen bis 0.67 sind unter http://blog.alivate.com.au/poppler-windows/ verfügbar. Beachten Sie jedoch, dass 0.68 im August 2018 veröffentlicht wurde, sodass Sie nicht die neuesten Funktionen oder Fehlerbehebungen erhalten.


4
Hallo, der Poppler ist nur eine komprimierte Datei, installiert nichts, was soll man mit den DLLs oder den Bin-Dateien machen?
Gaurwraith

@ Gaurwraith: Verwenden Sie den folgenden Link zu Poppler . Aus irgendeinem Grund ist der Link in der Beschreibung von Rodrigo nicht der gleiche wie im Github-Repo.
Tobias

@ Kevin Dave Haben Sie Poppler installiert und pdf2image auf einem Windows-Computer ausprobiert? Welches Windows bitte?
SKR

1
@elPastor Sie können first_page und last_page im Argument der Funktion conver_from_path hinzufügen, um nur die angegebene Seite zu konvertieren
Keval Dave

1
@ Jacob 500 ist die dpi. Es ist ein Kompromiss zwischen der erforderlichen Auflösung und der verfügbaren Berechnung. In meinen Experimenten haben 500 in den meisten Fällen gut funktioniert, während 300 mir Bilder mit niedriger Auflösung brachten.
Keval Dave

32

Ich fand diese einfache Lösung, PyMuPDF , Ausgabe in PNG-Datei. Beachten Sie, dass die Bibliothek als "fitz" importiert wird, ein historischer Name für die verwendete Rendering-Engine.

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)

1
Bitte fügen Sie Ihrer Antwort eine Erklärung hinzu.
Shanteshwar Inde

1
Eine gute Bibliothek, die problemlos unter Windows 10 installiert werden kann (keine Räder erforderlich). github.com/pymupdf
Genosse Che

6
Dies ist die beste Antwort. Dies war der einzige Code, für den keine zusätzliche Installation auf meinem Betriebssystem erforderlich war. Python-Skripte sollten sich auf die Arbeit im Python-System konzentrieren. Ich musste Poppler, pdftoppm, imageMagick oder Ghostscript usw. nicht installieren (Python 3.6)
ZStoneDPM

1
Tatsächlich erfordert es eine andere Installation (Fitz-Bibliothek, importiert, ohne dass darauf verwiesen wird, und ihre Abhängigkeiten). Diese Antwort ist unvollständig (wie alle Antworten auf diese Frage)
Tommaso Guerrini

1
image = page.getPixmap(matrix=fitz.Matrix(150/72,150/72))extrahiert das Bild mit 150 DPI. Stellen Sie eine Frage zu diesem Thema.
Josiah Yoder

18

Die Python-Bibliothek pdf2image(in der anderen Antwort verwendet) macht in der Tat nicht viel mehr als nur das Starten pdttoppm mit subprocess.Popen. Hier ist eine kurze Version, die dies direkt tut:

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))

Hier ist der Windows-Installationslink für pdftoppm(in einem Paket namens poppler enthalten): http://blog.alivate.com.au/poppler-windows/


4
Hallo, der Windows-Installationslink für pdftoppm ist nur ein Bündel von komprimierten Dateien. Was müssen Sie damit tun, damit sie funktionieren? Vielen Dank!
Gaurwraith

14

Es ist nicht erforderlich, Poppler auf Ihrem Betriebssystem zu installieren. Das wird funktionieren:

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)

10
Die ImageMagick-Bibliothek muss installiert sein, damit der Zauberstab bearbeitet werden kann.
Neeraj Gulia

2
Ich habe dies versucht und musste auch Ghostscript installieren (unter Windows 10 und Python 3.7). Hab es geschafft und es hat perfekt funktioniert.
JCF

1
Wofür ist das f [: - 4]? es wird nirgendwo anders erwähnt
Ari

@Ari f [: - 4] schneidet ".pdf" aus dem Dateinamen (String Slicing), um einen neuen Dateinamen mit einem anderen ext zu erstellen.
Fabian

9

@gaurwraith, installiere poppler für Windows und verwende pdftoppm.exe wie folgt:

  1. Laden Sie die Zip-Datei mit den neuesten Binärdateien / DLLs von Poppler von http://blog.alivate.com.au/poppler-windows/ herunter und entpacken Sie sie in einen neuen Ordner in Ihrem Programmdateienordner. Zum Beispiel: "C: \ Programme (x86) \ Poppler".

  2. Fügen Sie Ihrer Umgebungsvariablen SYSTEM PATH "C: \ Programme (x86) \ Poppler \ poppler-0.68.0 \ bin" hinzu.

  3. Installieren Sie in der cmd-Zeile das Modul pdf2image -> "pip install pdf2image".

  4. Alternativ können Sie pdftoppm.exe direkt aus Ihrem Code mithilfe des Python-Unterprozessmoduls ausführen, wie vom Benutzer Basj erläutert.

@vishvAs vAsuki, dieser Code sollte die gewünschten JPGs über das Unterprozessmodul für alle Seiten eines oder mehrerer PDFs in einem bestimmten Ordner generieren:

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))

Oder verwenden Sie das Modul 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")

Das hat sehr geholfen. Vielen Dank!
Sreekiran

1
Dies sollte eigentlich die akzeptierte Antwort sein. Zeigt, was mit den installierten Binärdateien für Poppler
Kunj Mehta

3

Es gibt ein Dienstprogramm namens pdftojpg, mit dem das PDF in img konvertiert werden kann

Den Code finden Sie hier 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
Hat diese Java-Sache gerade meinen gesamten Ordner voller PDF-Dateien gelöscht, die Python-Skripte manipulieren?
Ulf Gjerdingen

1

GhostScript ist für ein Linux-basiertes System viel schneller als Poppler.

Im Folgenden finden Sie den Code für die Konvertierung von PDF in Bilder.

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 kann unter macOS mit installiert werden brew install ghostscript

Installationsinformationen für andere Plattformen finden Sie hier . Wenn es noch nicht auf Ihrem System installiert ist.


0

Ich benutze eine (vielleicht) viel einfachere Option von 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

Dies ist ein kleiner Teil eines Bash-Skripts in einer Schleife für die Verwendung eines schmalen Casting-Geräts. Überprüft alle 5 Sekunden hinzugefügte PDF-Dateien (alle) und verarbeitet sie. Dies ist für ein Demo-Gerät, am Ende wird die Konvertierung auf einem Remote-Server durchgeführt. Jetzt in .PNG konvertieren, aber auch .JPG ist möglich.

Diese Konvertierung zusammen mit Übergängen im A4-Format, der Anzeige eines Videos, zweier flüssiger Bildlauftexte und eines Logos (mit Übergang in drei Versionen) setzt den Pi3 auf fast 4x 100% CPU-Last ;-)


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')

Dies wäre eine bessere Antwort, wenn Sie erklären würden, wie der von Ihnen bereitgestellte Code die Frage beantwortet.
pppery

1
@pppery Python ist ziemlich lesbar, die Kommentare geben den Quellordner und den Ausgabeordner an, der Rest liest sich wie Englisch.
Ari

-1

Hier ist eine Lösung, die keine zusätzlichen Bibliotheken erfordert und sehr schnell ist. Dies wurde gefunden von: https://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html# Ich habe den Code in eine Funktion eingefügt, um es bequemer zu machen.

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

Rufen Sie convert mit dem PDF-Pfad als Argument auf, und die Funktion erstellt eine JPG-Datei im selben Verzeichnis


1
Diese Technik sieht so aus, als würde sie Bilder extrahieren, die in die Datei eingebettet wurden, anstatt eine Seite der Datei als Bild zu rasteren, was der Fragesteller wollte.
Josh Gallagher
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.