PDFからページをJPEGとして抽出する


95

Pythonコードで、pdfの特定のページをjpegファイルとして効率的に保存する方法は?(使用例:私はpdf-sがアップロードされ、各ページに対応するjpeg-sがストアであるpythonフラスコWebサーバーを持っています。)

この解決策は近いですが、問題はページ全体がjpegに変換されないことです。


1
画像によっては、pngとして抽出した方がよい場合があります。これは、ページに主にテキストが含まれている場合に適用されます。
ポールルーニー

回答:


125

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 repo pdf2imageは、それが使用しpdftoppm、他のインストールが必要であることも言及しています:

pdftoppmは、実際の魔法を行うソフトウェアです。popplerと呼ばれるより大きなパッケージの一部として配布されます。Windowsユーザーはpoppler for Windowsをインストールする必要があります。Macユーザーはpoppler for Macをインストールする必要があります。Linuxユーザーは、ディストリビューション(UbuntuとArchlinuxでテスト済み)にpdftoppmがプリインストールされている場合は、実行しsudo apt install poppler-utilsます。

次のようにして、anacondaを使用してWindowsに最新バージョンをインストールできます。

conda install -c conda-forge poppler

注:0.67までのWindowsバージョンはhttp://blog.alivate.com.au/poppler-windows/で入手できますが、0.68は2018年8月リリースされたため、最新の機能やバグ修正を取得できないことに注意してください。


4
こんにちは、popplerは単なるzipファイルであり、何もインストールしません。dllまたはbinファイルで何を行うことになっていますか?
gaurwraith

@gaurwraith:poppler の次のリンクを使用してください。何らかの理由で、Rodrigoの説明にあるリンクはgithubリポジトリのリンクと同じではありません。
Tobias、

@Keval Dave popplerをインストールして、Windowsマシンでpdf2imageを試しましたか?どのWindowsを使用しますか?
SKR、

1
@elPastor conver_from_path関数の引数にfirst_pageとlast_pageを追加して、指定したページのみを変換できます
Keval Dave

1
@Jacob 500はdpiです。必要な解像度と利用可能な計算のトレードオフです。私の実験では、ほとんどの場合500枚で問題なく動作し、300枚で低解像度の画像が得られました。
Keval Dave

36

この単純な解決策である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)

1
回答に説明を追加してください。
Shanteshwar Inde

1
優れたライブラリであり、Windows 10に問題なくインストールされます(ホイールは不要)。github.com/pymupdf
同志チェ

7
これが最良の答えです。これは、私のOSに追加のインストールを必要としない唯一のコードでした。Pythonスクリプトは、Pythonシステム内での作業に焦点を当てる必要があります。poppler、pdftoppm、imageMagick、ghostscriptなどをインストールする必要はありませんでした(Python 3.6)
ZStoneDPM

1
実際には、別のインストールが必要です(fitzライブラリー、参照されずにインポートされ、その依存関係も)、この回答は不完全です(この質問のすべての回答と同様)
Tommaso Guerrini

1
@JJPtyパスから取得したpdfファイルの代わりに、pdfurlから取得できますか?また、pngファイルがoutput-pngファイルではなくインストリームデータであることは可能ですか?
Shubham Agrawal

18

pdf2image実際、Pythonライブラリ(他の回答で使用されています)は、で起動 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/は、


4
こんにちは。pdftoppmのWindowsインストールリンクは、圧縮されたファイルのほんの一部です。それらを機能させるために、それらをどのように処理する必要がありますか?ありがとう!
gaurwraith

14

お使いのOSにPopplerをインストールする必要はありません。これは動作します:

pand 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
ワンドで動作するには、ImageMagickライブラリをインストールする必要があります。
Neeraj Gulia

2
私はこれを試し、Ghostscriptもインストールする必要がありました(Windows 10とPython 3.7を使用)。それをやった、それは完全に働いた。
jcf

1
f [:-4]とは それは他のどこにも参照されていません
Ari

@Ari f [:-4]は、ファイル名(文字列スライス)から「.pdf」を切り取り、他の拡張子を持つ新しいファイル名を作成します。
Fabian

9

@ gaurwraith、Windows用の popplerをインストールしpdftoppm.exeを次のように使用します。

  1. Popplerの最新のバイナリ/ dllを含むzipファイルを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. コマンドラインからpdf2imageモジュールをインストール->「pip install pdf2image」。

  4. または、ユーザーBasjで説明されているように、Pythonのサブプロセスモジュールを使用して、コードからpdftoppm.exeを直接実行します。

@vishvAs vAsukiの場合、このコードは、指定されたフォルダー内の1つ以上のpdfのすべてのページについて、サブプロセスモジュールを通じて必要なjpgを生成する必要があります。

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

これは大いに役立ちました。ありがとう!
Sreekiran、

1
これは実際に受け入れられる答えになるはずです。インストールされているPopplerのバイナリをどうするかを示してい
ます

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のことは、pythonスクリプトを操作するPDFでいっぱいの私のフォルダ全体を削除しただけですか...
Ulf Gjerdingen

2

Linuxベースのシステムでは、GhostScriptはPopplerよりもはるかに高速に実行されます。

以下は、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スクリプトの小さな部分です。追加されたPDFファイル(すべて)を5秒ごとにチェックして処理します。これはデモデバイス用で、最後に変換はリモートサーバーで行われます。現在.PNGに変換していますが、.JPGも可能です。

この変換は、A4形式のトランジションとともに、ビデオ、2つのスムーズスクロールテキスト、およびロゴ(3つのバージョンのトランジション付き)を表示して、Pi3をほぼ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')

あなたが提供したコードがどのように質問に答えるかを説明したなら、これはより良い答えでしょう。
pppery

1
@pppery Pythonはかなり読みやすく、コメントはソースフォルダーと出力フォルダーを示し、残りは英語のように表示されます。
Ari

-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

pdfパスを引数としてconvertを呼び出すと、関数は同じディレクトリに.jpgファイルを作成します


1
この手法は、ファイルのページを画像としてラスタライズするのではなく、ファイルに埋め込まれている画像を抽出するように見えます。
Josh Gallagher
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.