PythonでPDF内のテキストと画像の正確な位置を取得する方法

PDF文書を処理および分析する際、ページ上のテキストや画像の正確な位置を取得することは重要な操作です。これらの要素の具体的な座標を把握することで、PDFコンテンツの詳細な制御や理解が可能になり、文書の自動処理、情報抽出、コンテンツの再構築などの作業フローにおいて特に重要です。Pythonを使用することで、PDFページ上のテキストや画像の正確な座標を簡単に取得でき、元のレイアウトを崩すことなくコンテンツを操作することができます。本記事では、**Pythonを使用してPDF内のテキストと画像の位置座標を取得する方法**を紹介します。

- **[PythonでPDF内のテキストを検索し、その座標を取得](#pythonでpdf内のテキストを検索しそのページ座標を取得)**
- **[PythonでPDFページ内の特定の画像の座標を取得](#pythonでpdfページ内の特定の画像の座標を取得)**

本記事で使用する方法には、[Spire.PDF for Python](https://jp.e-iceblue.com/introduce/spire-pdf-for-python.html)が必要です。PyPIからインストール可能です：`pip install spire.pdf`

Spire.PDF for Pythonは、PDFページ上の要素の位置を左上原点の座標系で扱います。この座標系では、x軸は右方向に、y軸は下方向に伸びます。PDFページにテキストや画像などのコンテンツを配置する際、x座標とy座標を使用して位置を特定できます。また、ライブラリのプロパティを使用して、ページ上の指定要素の位置を取得することも可能です。
以下の図はページ座標の例を示しています：

![Spire.PDF for Pythonのページ座標例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/5276f3ab-52df-6ca8-5c31-bc52475e28c2.png)

# PythonでPDF内のテキストを検索し、そのページ座標を取得

`PdfTextFinder`クラスを使用すると、指定したPDFページ内で特定のオプションを用いてテキストを検索できます。検索したテキストについて、`PdfTextFragment.Positions[0].X`および`PdfTextFragment.Positions[0].Y`プロパティを利用してテキストの開始座標にアクセスし、その正確な位置を特定できます。

さらに、`PdfTextFragment`クラスは、`Text`、`TextStates[].FontSize`、および`TextStates[].FontName`プロパティを提供しており、テキストの詳細情報を取得することができます。これにより、テキストの完全なコピーなども可能です。

以下は、PythonでPDF内のテキストのページ座標を取得する操作手順の例です：

1. 必要なモジュールをインポート：`PdfDocument`、`PdfTextFinder`、`PdfTextFindOptions`、および`TextFindParameter`
2. `PdfDocument`インスタンスを作成し、`PdfDocument.LoadFromFile()`メソッドで操作対象のPDFを読み込む
3. `PdfDocument.Pages.get_Item()`で特定のページを取得、または全ページをループ処理
4. ページを使用して`PdfTextFinder`インスタンスを作成
5. `PdfTextFindOptions`インスタンスを作成し、`PdfTextFindOptions.Parameter`プロパティで`TextFindParameter`を使用して検索オプションを設定
6. `PdfTextFinder.Options`で検索オプションを適用
7. `PdfTextFinder.Find(str: text)`メソッドで指定テキストを検索
8. 検索結果があるか確認し、あれば結果をループ処理し、`PdfTextFragment.Positions[0].X`および`PdfTextFragment.Positions[0].Y`プロパティで座標を取得
9. 結果を出力する、または他の操作を行う

**コード例**
```python
from spire.pdf import PdfDocument, PdfTextFinder, PdfTextFindOptions, TextFindParameter

# PdfDocument のインスタンスを作成
pdf = PdfDocument()

# PDF ドキュメントを読み込む
pdf.LoadFromFile("Sample.pdf")

textFound = False # テキストが見つかったかを確認するフラグ
# すべてのページをループ
for i in range(pdf.Pages.Count):
    # ページを取得
    page = pdf.Pages.get_Item(i)

    # PdfTextFinder のインスタンスを作成
    finder = PdfTextFinder(page)

    # 検索オプションを設定
    options = PdfTextFindOptions()
    options.Parameter = TextFindParameter.WholeWord
    finder.Options = options

    # テキストを検索
    results = finder.Find("History and Cultural Significance")
    # テキストが見つかったかどうかを確認
    if len(results) > 0:
        textFound = True # 見つかったとマーク
        # すべての結果をループ
        for text in results:
            # 開始座標を取得
            x = text.Positions[0].X
            y = text.Positions[0].Y
            # 終了座標を取得
            x2 = text.Positions[-1].X
            print("テキストが見つかりました: ページ " + str(i+1) + "。座標:\n" + "X: " + str(x) + "\nY: " + str(y) + "\n")
# テキストが見つからなかった場合のメッセージを表示
if not textFound:
    print("テキストが見つかりませんでした。")

pdf.Close()
```

結果
![PythonでPDFテキストの座標を取得](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/a7dccb30-480b-12fb-fe1e-6e1309ccba0f.png)

## PythonでPDFページ内の特定の画像の座標を取得

`PdfPageBase.ImagesInfo`プロパティを使用すると、指定したPDFページの画像情報リストを取得できます。このリストをループ処理することで、`PdfImageInfo.Bounds.X`および`PdfImageInfo.Bounds.Y`プロパティから画像の開始座標を取得可能です。また、`PdfImageInfo.Image`プロパティを利用して画像を`Stream`形式で取得し、保存やコピーなどの操作も行えます。

以下は、PDF画像のページ座標を取得する操作手順の例です：

1. 必要なモジュールをインポート：`PdfDocument`
2. `PdfDocument`インスタンスを作成し、`PdfDocument.LoadFromFile()`メソッドで操作対象のPDFを読み込む
3. `PdfDocument.Pages.get_Item()`で特定のページを取得、または全ページをループ処理
4. `PdfPageBase.ImagesInfo`プロパティを使用してページの画像情報リストを取得
5. ページに画像が含まれているか確認し、含まれていれば画像情報リストをループ処理して`PdfImageInfo.Bounds.X`および`PdfImageInfo.Bounds.Y`プロパティで画像の開始座標を取得
6. 結果を出力する、または画像の他の操作を行う

**コード例**
```python
from spire.pdf import PdfDocument

# PdfDocument のインスタンスを作成
pdf = PdfDocument()

# PDF ドキュメントを読み込む
pdf.LoadFromFile("Sample.pdf")

imageFound = False # 画像が見つかったかどうかを示すフラグ
# すべてのページをループ
for i in range(pdf.Pages.Count):
    # ページを取得
    page = pdf.Pages.get_Item(i)
    # ページの画像情報を取得
    imagesInfo = page.ImagesInfo
    # ページに画像が含まれているか確認
    if len(imagesInfo) > 0:
        imageFound = True # 見つかったとマーク
        # すべての画像をループ
        for j in range(len(imagesInfo)):
            # 画像情報を取得
            imageInfo = page.ImagesInfo[j]
            # 画像の座標を取得
            x = imageInfo.Bounds.X
            y = imageInfo.Bounds.Y
            # 座標を出力
            print(f"ページ {i + 1} の画像 {j + 1}。座標: \n座標: X={x}, Y={y}")
# 画像が見つからなかった場合のメッセージを表示
if not imageFound:
    print("ドキュメントに画像が含まれていません。")
pdf.Close()
```

結果
![PythonでPDF画像の座標を取得](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/3c58ec77-9062-5c75-3a74-8e1d5035c324.png)

本記事では、Pythonを使用してPDF文書内のテキストや画像の位置座標を取得し、その正確な位置を特定する方法について説明しました。

[無料ライセンス申請](https://www.e-iceblue.com/TemLicense.html)