Ekstrak halaman dari pdf sebagai jpeg


100

Dalam kode python, bagaimana cara efisien menyimpan halaman tertentu dalam pdf sebagai file jpeg? (Kasus penggunaan: Saya memiliki server web python flask di mana pdf-s akan diunggah dan jpeg-s yang sesuai dengan setiap halaman disimpan.)

Solusi ini sudah dekat, tetapi masalahnya tidak mengubah seluruh halaman menjadi jpeg.


1
Bergantung pada gambarnya, mungkin lebih baik mengekstraknya sebagai png. Ini akan berlaku jika halaman berisi sebagian besar teks.
Paul Rooney

Jawaban:


133

Perpustakaan pdf2image dapat digunakan.

Anda dapat menginstalnya hanya dengan menggunakan,

pip install pdf2image

Setelah terinstal, Anda dapat menggunakan kode berikut untuk mendapatkan gambar.

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

Menyimpan halaman dalam format jpeg

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

Sunting: Github repo pdf2image juga menyebutkan bahwa ia menggunakan pdftoppmdan membutuhkan instalasi lain:

pdftoppm adalah perangkat lunak yang melakukan keajaiban yang sebenarnya. Ini didistribusikan sebagai bagian dari paket yang lebih besar yang disebut poppler . Pengguna Windows harus menginstal poppler untuk Windows . Pengguna Mac harus menginstal poppler untuk Mac . Pengguna Linux akan memiliki pdftoppm yang telah diinstal sebelumnya dengan distro (Diuji di Ubuntu dan Archlinux) jika tidak, jalankan sudo apt install poppler-utils.

Anda dapat menginstal versi terbaru di bawah Windows menggunakan anaconda dengan melakukan:

conda install -c conda-forge poppler

catatan: Versi Windows hingga 0.67 tersedia di http://blog.alivate.com.au/poppler-windows/ tetapi perhatikan bahwa 0.68 dirilis pada Agustus 2018 sehingga Anda tidak akan mendapatkan fitur terbaru atau perbaikan bug.


4
Hai, poppler hanyalah file zip, tidak menginstal apa pun, apa yang harus dilakukan dengan dll atau file bin?
gaurwraith

@gaurwraith: Gunakan link berikut ke poppler . Untuk beberapa alasan, tautan dalam deskripsi dari Rodrigo tidak sama dengan di repo github.
Tobias

1
@elPastor Anda dapat menambahkan first_page dan last_page dalam argumen fungsi conver_from_path untuk mengonversi halaman tertentu saja
Keval Dave

1
@Jacob 500 adalah dpi. Ini tradeoff pada resolusi yang diperlukan dan perhitungan yang tersedia. Dalam percobaan saya, 500 bekerja dengan baik pada kebanyakan kasus sementara 300 memberi saya gambar rez rendah.
Keval Dave

1
Untuk mengonversi halaman pertama PDF dan tidak ada yang lain, ini berfungsi: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

Saya menemukan solusi sederhana ini, PyMuPDF , output ke file png. Perhatikan bahwa pustaka diimpor sebagai "fitz", nama historis untuk mesin rendering yang digunakannya.

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
Tolong tambahkan penjelasan untuk jawaban Anda.
Shanteshwar Inde

1
Perpustakaan yang bagus dan diinstal pada Windows 10 tanpa masalah (tidak diperlukan roda). github.com/pymupdf
Kamerad Che

7
Ini adalah jawaban TERBAIK. Ini adalah satu-satunya kode yang tidak memerlukan instalasi tambahan ke OS saya. Skrip Python harus fokus bekerja dalam sistem Python. Saya tidak perlu menginstal poppler, pdftoppm, imageMagick atau ghostscript, dll. (Python 3.6)
ZStoneDPM

1
Sebenarnya itu membutuhkan instalasi lain (perpustakaan fitz, diimpor bahkan tanpa dirujuk dan dependensinya), jawaban ini tidak lengkap (seperti semua jawaban di pertanyaan ini)
Tommaso Guerrini

1
@JJPty Daripada file pdf diambil dari path, bisakah kita mengambil dari pdfurl? Selain itu, mungkinkah file png menjadi data in-stream daripada file output-png?
Shubham Agrawal

18

Python perpustakaan pdf2image(yang digunakan dalam jawaban lain) sebenarnya tidak melakukan lebih dari sekedar meluncurkan pdttoppm dengan subprocess.Popen, jadi di sini adalah melakukannya secara langsung pendek versi:

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

Berikut adalah tautan instalasi Windows untuk pdftoppm(terdapat dalam paket bernama poppler): http://blog.alivate.com.au/poppler-windows/


4
Hai, tautan penginstalan Windows untuk pdftoppm hanyalah sekumpulan file zip, apa yang harus Anda lakukan dengan file tersebut agar berfungsi? Terima kasih!
gaurwraith

14

Tidak perlu menginstal Poppler di OS Anda. Ini akan berhasil:

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

12
Pustaka ImageMagick perlu dipasang untuk bekerja pada penunjuk.
Neeraj Gulia

3
Saya mencoba ini dan perlu menginstal Ghostscript juga (menggunakan Windows 10 dan Python 3.7). Berhasil dan itu bekerja dengan sempurna.
jcf

1
untuk apa f [: - 4]? itu tidak dirujuk di tempat lain
Ari

@Ari f [: - 4] akan memotong ".pdf" dari nama file (string slicing) untuk membuat nama file baru dengan ext lainnya.
Fabian

10

@gaurwraith, instal poppler untuk Windows dan gunakan pdftoppm.exe sebagai berikut:

  1. Unduh file zip dengan binari / dll terbaru Poppler dari http://blog.alivate.com.au/poppler-windows/ dan unzip ke folder baru di folder file program Anda. Misalnya: "C: \ Program Files (x86) \ Poppler".

  2. Tambahkan "C: \ Program Files (x86) \ Poppler \ poppler-0.68.0 \ bin" ke variabel lingkungan SYSTEM PATH Anda.

  3. Dari baris cmd instal modul pdf2image -> "pip install pdf2image".

  4. Atau, langsung jalankan pdftoppm.exe dari kode Anda menggunakan modul subproses Python seperti yang dijelaskan oleh pengguna Basj.

@vishvAs vAsuki, kode ini harus menghasilkan jpg yang Anda inginkan melalui modul subprocess untuk semua halaman dari satu atau lebih pdf dalam folder tertentu:

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

Atau menggunakan 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")

Ini sangat membantu. Terima kasih!
Sreekiran

1
Ini seharusnya menjadi jawaban yang diterima. Menunjukkan apa yang harus dilakukan dengan binari yang diinstal untuk Poppler
Kunj Mehta

3

Mereka adalah utilitas yang disebut pdftojpg yang dapat digunakan untuk mengonversi pdf ke img

Anda dapat menemukan kodenya di sini 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
apakah hal java ini hanya menghapus seluruh folder saya yang penuh dengan pdf yang memanipulasi skrip python ....?
Ulf Gjerdingen

2

GhostScript bekerja jauh lebih cepat daripada Poppler untuk sistem berbasis Linux.

Berikut adalah kode untuk konversi pdf ke gambar.

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 dapat diinstal di macOS menggunakan brew install ghostscript

Informasi instalasi untuk platform lain dapat ditemukan di sini . Jika belum terinstal di sistem Anda.


0

Saya menggunakan opsi (mungkin) yang lebih sederhana dari 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

Ini adalah bagian kecil dari skrip bash dalam satu loop untuk penggunaan perangkat transmisi yang sempit. Memeriksa setiap 5 detik pada file pdf yang ditambahkan (semua) dan memprosesnya. Ini untuk perangkat demo, pada akhirnya konversi akan dilakukan di server jauh. Mengonversi ke .PNG sekarang, tetapi .JPG juga memungkinkan.

Konversi ini, bersama dengan transisi pada format A4, menampilkan video, dua teks bergulir mulus dan logo (dengan transisi dalam tiga versi) mengatur Pi3 ke semua 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')

Ini akan menjadi jawaban yang lebih baik jika Anda menjelaskan bagaimana kode yang Anda berikan menjawab pertanyaan.
pppery

2
@pppery Python cukup mudah dibaca, komentar menunjukkan folder sumber dan folder keluaran, sisanya berbunyi seperti bahasa Inggris.
Ari

-1

Berikut adalah solusi yang tidak memerlukan pustaka tambahan dan sangat cepat. Ini ditemukan dari: https://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html# Saya telah menambahkan kode dalam sebuah fungsi untuk membuatnya lebih nyaman.

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

Panggil convert dengan jalur pdf sebagai argumennya dan fungsinya akan membuat file .jpg di direktori yang sama


1
Teknik ini terlihat seperti mengekstrak gambar yang telah disematkan dalam file, daripada meraster halaman file sebagai gambar yang diinginkan oleh penanya.
Josh Gallagher
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.