PDF から画像を抽出する方法 - ツール別完全ガイド
PDF 内の画像構造を理解する
PDF から画像を正しく抽出するには、まず PDF ファイル内で画像がどのように格納されているかを理解する必要があります。PDF は単なる画像の集合ではなく、テキスト、ベクターグラフィックス、ラスター画像、フォントなどを統合した複合ドキュメント形式です。
PDF 内の画像格納方式:
- 埋め込みラスター画像: JPEG, JPEG2000, CCITT (FAX), Flate (PNG 相当) などの形式で圧縮されて格納。元の画像データがそのまま PDF 内に存在する
- インライン画像: 小さな画像がコンテンツストリーム内に直接埋め込まれる形式。抽出が困難な場合がある
- マスク画像: 透過情報を持つ画像。本体画像とマスクが別オブジェクトとして格納される
- Form XObject: 複数ページで再利用される画像やグラフィックスのコンテナ
抽出時の注意点:
- PDF 内の画像は表示サイズと実際の解像度が異なる場合がある (高解像度画像が小さく表示されている等)
- 1 つの見た目の画像が、複数のオブジェクト (本体 + マスク + カラースペース定義) で構成されていることがある
- スキャンされた PDF は各ページ全体が 1 枚の画像として格納されている
- PDF のセキュリティ設定 (パスワード保護、コピー禁止) により抽出が制限される場合がある
抽出方法の選択は、「元の画像データをそのまま取り出したい」のか「ページの見た目を画像化したい」のかで大きく異なります。前者は埋め込み画像の抽出、後者はページのレンダリング (ラスタライズ) です。
コマンドラインツールによる抽出
コマンドラインツールは、大量の PDF からの一括抽出やスクリプトへの組み込みに最適です。代表的なツールの使い方を解説します。
pdfimages (Poppler ユーティリティ):
PDF 内の埋め込み画像をそのまま (再圧縮なしで) 抽出する最も信頼性の高いツールです。
- インストール: macOS
brew install poppler、Ubuntuapt install poppler-utils - 基本コマンド:
pdfimages -all document.pdf output_prefix -allオプション: 画像を元のフォーマット (JPEG, PNG, TIFF 等) で抽出。このオプションなしだと PPM/PBM 形式に変換される-jオプション: JPEG 画像を JPEG のまま抽出 (非可逆圧縮の再適用を回避)-f/-lオプション: 抽出するページ範囲を指定 (例:-f 3 -l 7で 3-7 ページ)- 画像一覧の確認:
pdfimages -list document.pdfで埋め込み画像の情報 (サイズ、色空間、圧縮方式) を表示
pdftoppm (ページ全体のラスタライズ):
- ページ全体を画像に変換:
pdftoppm -png -r 300 document.pdf output_prefix -r 300: 解像度 300 DPI で出力 (印刷品質)- スキャン PDF やレイアウトごと画像化したい場合に使用
Ghostscript:
- 高品質なページレンダリング:
gs -dNOPAUSE -dBATCH -sDEVICE=png16m -r300 -sOutputFile=page_%03d.png document.pdf - PDF の描画エンジンとして最も正確な出力を生成
Python による画像抽出
Python を使えば、画像抽出のロジックをカスタマイズし、後処理 (リネーム、フィルタリング、変換) と組み合わせた柔軟なワークフローを構築できます。
PyMuPDF (fitz) - 推奨:
高速で機能豊富な PDF 操作ライブラリです。画像の抽出が非常に簡単に行えます。
import fitzdoc = fitz.open("document.pdf")for page_num in range(len(doc)): page = doc[page_num] images = page.get_images(full=True) for img_index, img in enumerate(images): xref = img[0] base_image = doc.extract_image(xref) image_bytes = base_image["image"] image_ext = base_image["ext"] with open(f"page{page_num+1}_img{img_index+1}.{image_ext}", "wb") as f: f.write(image_bytes)
PyMuPDF の利点:
- 元の画像フォーマットを維持して抽出 (再圧縮なし)
- 画像の解像度、色空間、サイズ情報も取得可能
- マスク画像の処理にも対応
- ページのレンダリング (ラスタライズ) も同一ライブラリで可能
pdf2image (Poppler ラッパー):
ページ全体を画像化する場合に便利です。内部で pdftoppm を呼び出します。
from pdf2image import convert_from_pathimages = convert_from_path("document.pdf", dpi=300)for i, image in enumerate(images): image.save(f"page_{i+1}.png", "PNG")
大量ページの PDF を処理する場合は、first_page と last_page パラメータでページ範囲を指定し、メモリ使用量を制御してください。
GUI ツールとオンラインサービス
コマンドラインやプログラミングに不慣れなユーザー向けに、GUI ツールとオンラインサービスを紹介します。ただし、機密文書の場合はオンラインサービスの利用を避け、ローカルツールを使用してください。
デスクトップ GUI ツール:
- Adobe Acrobat Pro: 「ツール → PDF を書き出し → 画像」で各ページを画像化。「編集 → 環境設定 → ページ表示」で解像度を設定。個別画像の抽出は「編集」モードで画像を右クリック → 「画像を別名で保存」
- PDF-XChange Editor (Windows): 無料版でも画像抽出が可能。「ドキュメント → 画像のエクスポート」で一括抽出
- プレビュー (macOS): PDF を開き、サイドバーでページサムネイルを選択 → ドラッグ & ドロップで画像として保存。ただし埋め込み画像の個別抽出は不可
- GIMP: PDF をインポートする際にページと解像度を選択可能。レイヤーとして読み込まれる
オンラインサービス (機密文書には非推奨):
- iLovePDF: ブラウザ上で PDF から画像を抽出。無料プランあり
- SmallPDF: PDF → 画像変換。ドラッグ & ドロップの簡単操作
- PDF24 Tools: ドイツ製の無料ツール。画像抽出とページ画像化の両方に対応
オンラインサービス利用時の注意:
- アップロードした PDF はサーバーに一時保存される。機密情報を含む文書は絶対にアップロードしない
- 利用規約でデータの取り扱いを確認する
- 処理後にサーバーからファイルが削除されるタイミングを確認する
- 可能な限りローカルツールを使用し、オンラインサービスは非機密文書に限定する
抽出画像の品質を最大化するテクニック
PDF から抽出した画像の品質を最大限に保つためのテクニックと、よくある問題への対処法を解説します。
品質を維持するための原則:
- 再圧縮を避ける: JPEG で格納されている画像は JPEG のまま抽出する。PNG に変換してもファイルサイズが増えるだけで品質は向上しない
- 元の解像度で抽出する: PDF 上の表示サイズではなく、埋め込まれた画像の実際の解像度で取り出す。
pdfimages -listで確認可能 - カラースペースを維持する: CMYK 画像を RGB に変換すると色が変わる。印刷用途なら CMYK のまま抽出する
よくある問題と対処法:
- 画像が分割されている: 1 つの見た目の画像が複数のタイルに分割されて格納されている場合がある。PyMuPDF の
page.get_pixmap()でページ全体をレンダリングし、必要な領域をクロップする方法が確実 - マスクが適用されていない: 透過画像が本体とマスクに分離されている。PyMuPDF は
extract_image()でマスクを自動適用するが、pdfimages では手動で合成が必要な場合がある - 色が異なる: ICC プロファイルが埋め込まれている場合、プロファイルを適用しないと色が変わる。
fitzのbase_image["colorspace"]で色空間を確認 - 回転・変形されている: PDF 上で画像が回転や変形されている場合、抽出される画像は変形前の状態。必要に応じて後処理で変形を適用する
スキャン PDF の場合:
スキャン PDF はページ全体が 1 枚の画像であるため、「画像の抽出」と「ページのレンダリング」が同義になります。pdftoppm -r 300 または PyMuPDF の page.get_pixmap(dpi=300) で高解像度に出力してください。
バッチ処理と自動化スクリプト
大量の PDF ファイルから画像を一括抽出する場合のバッチ処理スクリプトと、実務で役立つ自動化パターンを紹介します。
シェルスクリプトによるバッチ処理:
#!/bin/bashfor pdf in *.pdf; do dir="${pdf%.pdf}" mkdir -p "$dir" pdfimages -all "$pdf" "$dir/img"done
このスクリプトは、カレントディレクトリの全 PDF ファイルについて、PDF 名のフォルダを作成し、その中に画像を抽出します。
Python による高度なバッチ処理:
以下のようなカスタマイズが可能です:
- 最小サイズ以下の画像 (アイコン、装飾) をフィルタリング
- 抽出画像のファイル名を「PDF 名_ページ番号_連番」形式に統一
- 特定の解像度以上の画像のみ抽出
- 抽出後に自動的に WebP に変換してファイルサイズを削減
- CSV レポートの生成 (抽出した画像の一覧、サイズ、フォーマット)
実務での活用パターン:
- 報告書からの図表抽出: 社内報告書の PDF から図表だけを抽出し、プレゼン資料に再利用
- カタログからの商品画像抽出: 商品カタログ PDF から商品画像を一括抽出し、EC サイトに登録
- 論文からの図版抽出: 学術論文の PDF から図版を抽出し、引用・参照用に整理
- スキャン文書の OCR 前処理: スキャン PDF からページ画像を抽出し、OCR エンジンに渡す
注意事項:
- 著作権に注意: 他者が作成した PDF から画像を抽出して再利用する場合、著作権法に抵触しないか確認する
- パスワード保護された PDF:
qpdf --decryptでパスワードを解除してから処理する (正当な権限がある場合のみ) - 大容量 PDF: メモリ不足を防ぐため、ページ単位で処理する設計にする