Extraire une page d'un pdf au format jpeg


96

En code python, comment enregistrer efficacement une certaine page dans un pdf en tant que fichier jpeg? (Cas d'utilisation: j'ai un serveur Web flask python où les pdf-s seront téléchargés et les jpeg-s correspondant à chaque page sont stockés.)

Cette solution est proche, mais le problème est qu'elle ne convertit pas la page entière en jpeg.


1
Selon l'image, il peut être préférable d'extraire au format png. Cela s'appliquerait si la page contient principalement du texte.
Paul Rooney

Réponses:


126

La bibliothèque pdf2image peut être utilisée.

Vous pouvez l'installer simplement en utilisant,

pip install pdf2image

Une fois installé, vous pouvez utiliser le code suivant pour obtenir des images.

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

Enregistrer des pages au format jpeg

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

Edit: le repo Github pdf2image mentionne également qu'il utilise pdftoppmet qu'il nécessite d'autres installations:

pdftoppm est le logiciel qui fait la magie. Il est distribué dans le cadre d'un plus grand package appelé poppler . Les utilisateurs de Windows devront installer poppler pour Windows . Les utilisateurs de Mac devront installer poppler pour Mac . Les utilisateurs de Linux auront pdftoppm préinstallé avec la distribution (testé sur Ubuntu et Archlinux) si ce n'est pas le cas, exécutez sudo apt install poppler-utils.

Vous pouvez installer la dernière version sous Windows en utilisant anaconda en faisant:

conda install -c conda-forge poppler

Remarque: les versions de Windows jusqu'à 0.67 sont disponibles sur http://blog.alivate.com.au/poppler-windows/ mais notez que la version 0.68 a été publiée en août 2018 , vous n'obtiendrez donc pas les dernières fonctionnalités ou corrections de bogues.


4
Salut, le poppler est juste un fichier zippé, n'installe rien, que doit-on faire avec les fichiers dll ou bin?
gaurwraith

@gaurwraith: utilisez le lien suivant pour poppler . Pour une raison quelconque, le lien dans la description de Rodrigo n'est pas le même que dans le repo github.
Tobias

@Keval Dave Avez-vous installé poppler et essayé pdf2image sur une machine Windows? Quelle Windows s'il vous plaît?
SKR

1
@elPastor, vous pouvez ajouter first_page et last_page en argument de la fonction conver_from_path pour convertir uniquement la page spécifiée
Keval Dave

1
@Jacob 500 est le dpi. Il fait un compromis sur la résolution requise et le calcul disponible. Dans mes expériences, 500 ont bien fonctionné la plupart des cas tandis que 300 m'ont permis d'obtenir des images à faible rez.
Keval Dave

37

J'ai trouvé cette solution simple, PyMuPDF , sortie dans un fichier png. Notez que la bibliothèque est importée en tant que "fitz", un nom historique pour le moteur de rendu qu'elle utilise.

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
Veuillez ajouter une explication à votre réponse.
Shanteshwar Inde

1
Une bonne bibliothèque et elle s'installe sur Windows 10 sans problèmes (pas de roues requises). github.com/pymupdf
Comrade Che

7
C'est la meilleure réponse. C'était le seul code qui ne nécessitait pas d'installation supplémentaire sur mon système d'exploitation. Les scripts Python doivent se concentrer sur le travail dans le système Python. Je n'avais pas besoin d'installer poppler, pdftoppm, imageMagick ou ghostscript, etc. (Python 3.6)
ZStoneDPM

1
En fait elle nécessite une autre installation (bibliothèque fitz, importée sans même y être référencée et ses dépendances), cette réponse est incomplète (comme toutes les réponses à cette question)
Tommaso Guerrini

1
@JJPty Au lieu d'un fichier pdf extrait du chemin, pouvons-nous prendre pdfurl? En outre, est-il possible que le fichier png soit des données InStream plutôt qu'un fichier output-png?
Shubham Agrawal

18

La bibliothèque Python pdf2image(utilisée dans l'autre réponse) ne fait en fait pas beaucoup plus que simplement se lancer pdttoppm avec subprocess.Popen, voici donc une version courte qui le fait directement:

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

Voici le lien d'installation de Windows pour pdftoppm(contenu dans un package nommé poppler): http://blog.alivate.com.au/poppler-windows/


4
Salut, le lien d'installation de Windows pour pdftoppm n'est qu'un tas de fichiers zippés, qu'est-ce que vous avez à faire avec eux pour les faire fonctionner? Merci!
gaurwraith

14

Il n'est pas nécessaire d'installer Poppler sur votre système d'exploitation. Cela fonctionnera:

pip installer la baguette

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
La bibliothèque ImageMagick doit être installée pour fonctionner sur la baguette.
Neeraj Gulia

2
J'ai essayé cela et j'ai également dû installer Ghostscript (en utilisant Windows 10 et Python 3.7). Je l'ai fait et cela a parfaitement fonctionné.
jcf

1
à quoi sert le f [: - 4]? il n'est référencé nulle part ailleurs
Ari

@Ari f [: - 4] coupera ".pdf" du nom de fichier (découpage de chaîne) pour créer un nouveau nom de fichier avec un autre ext.
Fabian

9

@gaurwraith, installez poppler pour Windows et utilisez pdftoppm.exe comme suit:

  1. Téléchargez le fichier zip avec les derniers binaires / dll de Poppler à partir de http://blog.alivate.com.au/poppler-windows/ et décompressez-le dans un nouveau dossier dans votre dossier de fichiers de programme. Par exemple: "C: \ Program Files (x86) \ Poppler".

  2. Ajoutez «C: \ Program Files (x86) \ Poppler \ poppler-0.68.0 \ bin» à votre variable d'environnement SYSTEM PATH.

  3. Depuis la ligne cmd, installez le module pdf2image -> "pip install pdf2image".

  4. Ou bien, exécutez directement pdftoppm.exe à partir de votre code en utilisant le module de sous-processus de Python comme expliqué par l'utilisateur Basj.

@vishvAs vAsuki, ce code doit générer les jpgs souhaités via le module de sous-processus pour toutes les pages d'un ou plusieurs fichiers PDF dans un dossier donné:

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

Ou en utilisant le module 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")

Cela a beaucoup aidé. Merci!
Sreekiran

1
Cela devrait en fait être la réponse acceptée. Montre quoi faire avec les binaires installés pour Poppler
Kunj Mehta

3

Il s'agit d'un utilitaire appelé pdftojpg qui peut être utilisé pour convertir le pdf en img

Vous pouvez trouver le code ici 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
Est-ce que ce truc java vient de supprimer tout mon dossier plein de scripts python manipulant pdf ....?
Ulf Gjerdingen

2

GhostScript fonctionne beaucoup plus rapidement que Poppler pour un système basé sur Linux.

Voici le code pour la conversion de pdf en image.

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 peut être installé sur macOS en utilisant brew install ghostscript

Des informations d'installation pour d'autres plates-formes peuvent être trouvées ici . S'il n'est pas déjà installé sur votre système.


0

J'utilise une option (peut-être) beaucoup plus simple de 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

Il s'agit d'une petite partie d'un script bash dans une boucle pour l'utilisation d'un appareil de diffusion étroit. Vérifie toutes les 5 secondes les fichiers pdf ajoutés (tous) et les traite. Ceci est pour un appareil de démonstration, à la fin la conversion sera effectuée sur un serveur distant. Conversion en .PNG maintenant, mais .JPG est également possible.

Cette conversion, associée aux transitions au format A4, à l'affichage d'une vidéo, de deux textes à défilement fluide et d'un logo (avec transition en trois versions) définit le Pi3 à presque 4x 100% CPU-load ;-)


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

Ce serait une meilleure réponse si vous expliquiez comment le code que vous avez fourni répond à la question.
pppery

1
@pppery Python est assez lisible, les commentaires indiquent le dossier source et le dossier de sortie, le reste se lit comme l'anglais.
Ari

-1

Voici une solution qui ne nécessite aucune bibliothèque supplémentaire et qui est très rapide. Cela a été trouvé à partir de: https://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html# J'ai ajouté le code dans une fonction pour le rendre plus pratique.

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

Appelez convert avec le chemin pdf comme argument et la fonction créera un fichier .jpg dans le même répertoire


1
Cette technique semble extraire des images qui ont été incorporées dans le fichier, plutôt que de pixelliser une page du fichier en tant qu'image, ce que voulait le questionneur.
Josh Gallagher
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.