今回の記事ではPDFファイルの論文から画像を出力する方法を紹介します。

PyMuPDFとは

PyMuPDFは、PDF、XPS、OpenXPS、EPUBなどの様々なファイル形式を解析し、変換する作業をサポートするPythonのライブラリです。これは、MuPDFというC++で書かれたライブラリのPythonバインディングとして機能します。その名前は、「Python bindings for MuPDF」という意味から来ています。

Pythonバインディングとは何かというと、それはPythonから別のプログラミング言語(この場合はC++)で書かれたソフトウェアを操作できるようにするためのインターフェースのことです。つまり、PythonプログラムからC++のMuPDFライブラリの機能を利用できるようにするための「橋渡し」の役割を果たしているのです。

PyMuPDFの主な機能は以下のとおりです:

  1. テキストの抽出: PyMuPDFは、PDFなどのファイルからテキストを抽出する機能を提供します。これは、ファイル内の情報を自動的に収集したり、データ分析に利用するために非常に重要です。
  2. 画像の抽出: PyMuPDFはまた、PDF内の画像を抽出する能力も持っています。これは、図や表、写真などの視覚的な情報を別々のファイルとして取り出すことができるということを意味します。
  3. PDFの作成と編集: テキストや画像を追加、削除、変更することで、新しいPDFを作成したり、既存のPDFを編集したりすることも可能です。
  4. ページのレイアウト分析: ページ上のテキストや画像の配置を解析することもできます。これは、特定の情報がページのどの部分にあるのかを知るために役立ちます。

これらの機能は、特に大量のPDFファイルを扱う必要がある研究やビジネスの現場で非常に役立ちます。例えば、論文のテキスト分析を行う研究者や、ビジネスレポートから情報を抽出する企業などが、このライブラリを活用して作業の効率化を図ることができます。

実装

ここからはGoogle colabを使用して実装していきます。
(Google colabの使用方法はこちら⇨使い方

Open In Colab

まずは必要なライブラリをインストールします。

# 必要なライブラリをインストールする
!pip install PyMuPDF
!pip install Pillow

次にPDFファイルをアップロードします。

今回はこちらの論文(PDFファイル)で実装します。

# Google Colab のファイルアップロード機能を使うためのモジュールをインポートする
from google.colab import files
# ユーザーからのファイルアップロードを受け付ける。アップロードされたファイルは辞書形式で格納される。
uploaded = files.upload()

アップロードされたPDFファイルから画像を抽出し、それらの画像を個別のファイルとして保存することができます。また、画像が見つかった場合や見つからなかった場合にメッセージを出力するようにします。

# PDFファイルを操作するためのモジュールであるfitzと、画像を操作するためのモジュールであるPILをインポートする
import fitz
import io
from PIL import Image

# アップロードされた全てのファイルに対して処理を行う
for fn in uploaded.keys():
  # 最後にアップロードされたファイル名を取得する
  input_pdf = fn

# PDFファイルを開き、その内容をpdf_fileに格納する
pdf_file = fitz.open(input_pdf)

# PDFファイルの各ページに対して処理を行う
for page_index in range(len(pdf_file)):

    # ページを指定してその内容を取得する
    page = pdf_file[page_index]
    # そのページの中にある画像のリストを取得する
    image_list = page.get_images()
    # もし画像があればその数を出力する
    if image_list:
        print(f"[+] Found {len(image_list)} images in page {page_index}")
    # 画像がなければその旨を出力する
    else:
        print("[!] No images found on the given pdf page", page_index)

    # ページの中の各画像に対して処理を行う
    for image_index, img in enumerate(page.get_images(), start=1):
        # 画像情報とそのインデックスを出力する
        print(img)
        print(image_index)
        # 画像のリファレンス番号を取得する
        xref = img[0]
        # リファレンス番号を使用して画像を抽出する
        base_image = pdf_file.extract_image(xref)
        # 抽出した画像のバイトデータと拡張子を取得する
        image_bytes = base_image["image"]
        image_ext = base_image["ext"]
        # バイトデータからPillowを使用して画像オブジェクトを作成する
        image = Image.open(io.BytesIO(image_bytes))
        # 作成した画像オブジェクトをファイルに保存する。ファイル名は "image{ページ番号}_{画像のインデックス}.{拡張子}"とする
        image.save(open(f"image{page_index+1}_{image_index}.{image_ext}", "wb"))

以下のように論文中の画像が出力されました。

まとめ

最後までご覧いただきありがとうございました。