見出し画像

[Python] PDFファイルのページを画像に変換するデスクトップアプリを作成する

はじめに

以前、PythonでPDFファイルを1ページずつ画像ファイルに変換するツールを作成しました。

今回は、このツールを、変換したいPDFのファイルパスや出力するフォルダを指定できるよう、PySimpleGUIライブラリを使用してデスクトップアプリに変更しました。その実装について、まとめます。

使用するライブラリ

PySimpleGUI

PythonでGUIアプリを作成できるライブラリです。
使用時にはインストールが必要です。

pip install PySimpleGUI

動作環境

  • windows11

  • Python 3.10.2

作成したアプリ

アプリでは、下記の部品を配置しました。

  • PDFファイル選択

  • 出力フォルダ選択

  • 変換ボタン

PDFファイルをページごとに画像変換するデスクトップツールのスクリーンショット

実装

全体の実装は、下記になります。

from pathlib import Path
import PySimpleGUI as sg
from pdf2image import convert_from_path

POPPLER_PATH = r"C:\XXXX\XXXXXXX\poppler\bin"

def save_pages_to_images(pages, folder_path, base_file_name):
    """ImageオブジェクトをPNGファイルとして保存する

    Args:
        pages (Image): PDFのページごとに変換したImageオブジェクト
        folder_path (Path): 出力フォルダのPathオブジェクト
        base_file_name (str): PDFファイルのベースネーム

    Returns:
        str: 実行結果メッセージ
    """
    message = f'{len(pages)}ファイルに変換しました\n\n'

    for i, page in enumerate(pages):
        image_f_name = f'{base_file_name}_{str(i).zfill(2)}.png'
        image_f_path = folder_path.joinpath(image_f_name)
        page.save(image_f_path, 'PNG')
        message += f'{image_f_path}\n'

    return message


def save_pdf_to_images(input_file, output_folder):
    """PDFファイルのページを画像ファイルに変換する

    Args:
        input_file (str): PDFファイルパス名
        output_folder (str): 出力フォルダパス名

    Returns:
        str: 実行結果メッセージ
    """
    input_file_path = Path(input_file)
    # 出力先フォルダが指定されていない場合、PDFファイルと同じフォルダに出力する
    if output_folder == '':
        output_folder_path = input_file_path.parent
    else:
        output_folder_path = Path(output_folder)

    base_file_name = input_file_path.stem

    # PDFをImageに変換
    pages = convert_from_path(input_file_path, poppler_path=POPPLER_PATH)

    # Imageを画像ファイルに保存
    message = save_pages_to_images(pages, output_folder_path, base_file_name)

    return message


def execute(window, values):
    """ボタン選択時の処理

    Args:
        window (Window): Windowオブジェクト
        values (dict): 入力欄の辞書
    """
    output_folder = values['output_folder']
    input_file = values['input_file']

    message = save_pdf_to_images(input_file, output_folder)

    window['text1'].update(message)


def main():
    title = 'PDFを画像ファイルに変換'
    output_folder = ''
    input_file = ''

    # アプリのレイアウト
    layout = [
        [sg.Text('PDFファイル', size=(14, 1)), 
        sg.Input(input_file, key='input_file'), 
        sg.FilesBrowse('選択', file_types=(('PDFファイル', '*.pdf'),))],
        [sg.Text('出力フォルダ', size=(14, 1)), sg.Input(output_folder, key='output_folder'), sg.FolderBrowse('選択')],
        [sg.Button('変換', size=(14, 1), pad=(5, 15), bind_return_key=True)],
        [sg.Multiline(key='text1', size=(60, 10))]
    ]

    # アプリ表示
    window = sg.Window(title, layout)

    # アプリの実行処理
    while True:
        event, values = window.read()
        if event is None:
            break
        if event == '変換':
            execute(window, values)

    window.close()

if __name__ == '__main__':
    main()

PDFファイルを画像に変換し、画像ファイルに保存する処理は、下記ご参照ください。

ライブラリのインポート

PySimpleGUIライブラリをインポートします。
sgという別名で使用するのが慣例となっています。

import PySimpleGUI as sg

画面表示とレイアウト

画面上に配置する部品を、設定します。

    # アプリのレイアウト
    layout = [
        # ①PDFファイル選択
        [sg.Text('PDFファイル', size=(14, 1)), 
        sg.Input(input_file, key='input_file'), 
        sg.FilesBrowse('選択', file_types=(('PDFファイル', '*.pdf'),))],
        # ②出力フォルダ選択
        [sg.Text('出力フォルダ', size=(14, 1)), sg.Input(output_folder, key='output_folder'), sg.FolderBrowse('選択')],
        # ③変換ボタン
        [sg.Button('変換', size=(14, 1), pad=(5, 15), bind_return_key=True)],
        # ④実行結果出力テキスト
        [sg.Multiline(key='text1', size=(60, 10))]
    ]

レイアウトは、リストで指定し、要素ごとに1行ずつ配置されます。

続いて、作成したレイアウトを画面に表示するには、windowメソッドを実行します。
第1引数には、ウィンドウのタイトル文字列を、第2引数には、設定したレイアウトを指定します。

window = sg.Window(title, layout)

イベント処理

終了まで、PDFファイルの選択、出力フォルダの選択、そして、「変換」ボタン選択時の処理を実行するための実装は、下記となります。

    # アプリの実行処理
    while True:
        event, values = window.read()
        if event is None:
            break
        if event == '変換':
            execute(window, values)

画面表示後のユーザー入力を取得するのは、readメソッドになります。
戻り値として、event、valuesが取得できます。

eventには、レイアウトで設定した部品の第1引数の文字列が取得できるので、設定したボタンの部品の第1引数と同じ場合、execute関数を呼び出して処理を行います。

また、valuesは、ユーザーが選択した情報が辞書型で格納されています。
キーは、レイアウトで設定した部品のキーワード引数:keyで指定したキーが格納され、バリューに選択した情報が格納されます。

続いて、execute関数で、ユーザーが選択した情報を取得し、PDFのページを画像に変換する処理を実行しています。

def execute(window, values):
    """ボタン選択時の処理

    Args:
        window (Window): Windowオブジェクト
        values (dict): 入力欄の辞書
    """
    output_folder = values['output_folder']
    input_file = values['input_file']

    message = save_pdf_to_images(input_file, output_folder)

    window['text1'].update(message)

また、実行結果を表示するため、updateメソッドで、指定した部品を更新しています。

window['text1'].update(message)

まとめ

今回は、PySimpleGUIライブラリを使って、PDFのページを画像に変換するデスクトップアプリに変更する方法について、まとめました。
各部品の設定など、細かい設定については、別途まとめていきます。

参考書籍、サイト

今回PySimpleGUIライブラリを使用するにあたり、下記の書籍、記事、Youtubeが大変参考になりました。
ありがとうございました!






この記事が気に入ったらサポートをしてみませんか?