プログラミング学習

Python × ChatGPTでPDFと画像を一括結合!GUIツールの作り方【Tkinter + PyMuPDF】

記事内に商品プロモーションを含む場合があります

「複数のPDFや画像をまとめて1つのファイルにしたい」と思ったことはありませんか?
市販ソフトでも可能ですが、無料で使えるPythonを活用すれば、自分好みのツールを作成できます。

今回は、ChatGPTでコードを生成・改良しながら、PDF+画像結合ツールを作った過程をご紹介します。

実際に私もブログ記事や業務資料をまとめる際に使っており、ドラッグ&ドロップで簡単にPDFが作成できるため、作業効率が大幅に向上しました。

必要なライブラリ

  • Tkinter(標準ライブラリ:GUI構築)
  • Pillow(画像処理用)
  • PyMuPDF(PDF操作用:fitzとして利用)
  • os(ファイル操作)
  • tkinterdnd2(ドラッグ&ドロップ対応用)

💡 補足:以下のコマンドで必要なライブラリをまとめてインストール可能です。

pip install pillow pymupdf tkinterdnd2

TkinterはPython標準に含まれているため、追加インストールは不要です。
特にPyMuPDFはPDFと画像を統合的に扱える高速ライブラリで、他のライブラリよりも安定性が高いのが特長です。

Pythonコード

以下が完成版のコードです。ChatGPTでコードを生成しながら改良を加え、実際に使えるGUIアプリとして仕上げました。

import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image
import os
import fitz  # PyMuPDF

from tkinterdnd2 import DND_FILES, TkinterDnD

def select_files():
    file_paths = filedialog.askopenfilenames(
        title="画像またはPDFファイルを選択",
        filetypes=[("Image or PDF Files", "*.png *.jpg *.jpeg *.bmp *.tiff *.pdf")]
    )
    for path in file_paths:
        file_list.insert(tk.END, path)

def select_output_path():
    output_path = filedialog.asksaveasfilename(
        defaultextension=".pdf",
        filetypes=[("PDF files", "*.pdf")],
        title="保存先を選択"
    )
    output_entry.delete(0, tk.END)
    output_entry.insert(0, output_path)

def convert_to_pdf():
    file_paths = file_list.get(0, tk.END)
    output_path = output_entry.get()

    if not file_paths:
        messagebox.showerror("エラー", "ファイルを選択してください。")
        return
    if not output_path:
        messagebox.showerror("エラー", "保存先を指定してください。")
        return

    try:
        doc = fitz.open()

        for path in file_paths:
            ext = os.path.splitext(path)[1].lower() #  1は半角に変換してください
            if ext in ['.png', '.jpg', '.jpeg', '.bmp', '.tiff']:
                img = Image.open(path)
                if img.mode != 'RGB':
                    img = img.convert('RGB')
                temp_path = "temp_image.pdf"
                img.save(temp_path)
                temp_pdf = fitz.open(temp_path)
                doc.insert_pdf(temp_pdf)
                temp_pdf.close()
                os.remove(temp_path)
            elif ext == '.pdf':
                pdf = fitz.open(path)
                doc.insert_pdf(pdf)
                pdf.close()

        doc.save(output_path)
        doc.close()
        messagebox.showinfo("成功", f"PDFファイルが保存されました:\n{output_path}")
    except Exception as e:
        messagebox.showerror("変換エラー", str(e))

def drop(event):
    files = root.tk.splitlist(event.data)
    for file in files:
        if os.path.isfile(file) and file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff', '.pdf')):
            file_list.insert(tk.END, file)

def move_up():
    selected = file_list.curselection()
    if not selected or selected[0] == 0:
        return
    index = selected[0]
    item = file_list.get(index)
    file_list.delete(index)
    file_list.insert(index - 1, item)
    file_list.select_set(index - 1)

def move_down():
    selected = file_list.curselection()
    if not selected or selected[0] == file_list.size() - 1:
        return
    index = selected[0]
    item = file_list.get(index)
    file_list.delete(index)
    file_list.insert(index + 1, item)
    file_list.select_set(index + 1)

def delete_selected():
    selected = file_list.curselection()
    for index in reversed(selected):
        file_list.delete(index)

# GUI構築
root = TkinterDnD.Tk()
root.title("PDF一括変換ツール(画像+PDF結合対応)")
root.geometry("540x550")

tk.Button(root, text="ファイルを選択(画像またはPDF)", command=select_files).pack(pady=5)

file_list = tk.Listbox(root, width=60, height=10, selectmode=tk.EXTENDED)
file_list.pack(pady=10)
file_list.drop_target_register(DND_FILES)
file_list.dnd_bind('<<Drop>>', drop)

order_frame = tk.Frame(root)
order_frame.pack(pady=5)
tk.Button(order_frame, text="↑ 上へ", command=move_up, width=10).pack(side=tk.LEFT, padx=5)
tk.Button(order_frame, text="↓ 下へ", command=move_down, width=10).pack(side=tk.LEFT, padx=5)
tk.Button(order_frame, text="削除", command=delete_selected, width=10).pack(side=tk.LEFT, padx=5)

tk.Button(root, text="保存先を選択", command=select_output_path).pack(pady=5)

output_entry = tk.Entry(root, width=60)
output_entry.pack(pady=5)

tk.Button(root, text="PDFに変換", command=convert_to_pdf, bg="lightblue").pack(pady=20)

root.mainloop()

GUIイメージ

ツール起動直後の画面

このように、ファイルリストに画像やPDFをドラッグ&ドロップで追加し、順序を並べ替えてから「PDFに変換」ボタンを押すだけで、複数ファイルを1つのPDFにまとめられます。

機能とこだわりポイント

  • 複数のPDF・画像をまとめて一括結合
  • ドラッグ&ドロップ対応で直感的にファイル追加
  • ファイルの順番入れ替え機能(↑↓ボタン)
  • 選択ファイルの削除機能

👉 今後の改良予定として、以下の機能も検討しています。

  • PDFの分解(ページごとの抽出)
  • 画像サイズや向きの自動調整
  • 大量ファイル対応のバッチ処理

ChatGPTを活用すれば、これらの機能追加もスムーズに行える点が大きなメリットです。

EXEファイル化でさらに便利に

Pythonスクリプトを毎回実行するのが面倒な方には、PyInstallerを使ったEXE化がおすすめです。

pyinstaller your_script.py --onefile

EXE化することで、タスクバーに固定したり、他人に配布したりすることも可能になります。
詳しい手順は以下の記事で解説しています。

Pythonを.exeに変換する方法|PyInstallerで配布用実行ファイルを作成する手順Pythonで作成したスクリプトを.exeファイルに変換すれば、タスクバーにピン止めして手軽に起動できるだけでなく、Python本体やラ...

補足情報

  • 環境依存の注意点:Windowsでは比較的動作しやすいですが、Mac/Linuxでは追加設定が必要な場合があります。
  • 処理速度:高解像度画像が多い場合は時間がかかるため、将来的に圧縮機能を組み込むとより便利です。
  • 代替ライブラリPyPDF2でもPDF結合は可能ですが、PyMuPDFのほうが高速で安定しているため、本記事ではPyMuPDFを採用しました。

既存ソフト・オンラインサービスとの比較

PDF編集といえば「Adobe Acrobat」などの市販ソフトや、Smallpdf などのオンラインサービスが有名です。これらは便利ですが、以下のような制約があります。

  • 市販ソフト:有料ライセンスが必要(年間契約やサブスクリプション費用が高額)
  • オンラインサービス:アップロード可能なファイルサイズや回数に制限がある
  • セキュリティ:機密性の高いファイルをインターネットにアップロードするリスク

これに対して、今回のPython自作ツールには以下のメリットがあります。

  • 完全無料:Python環境があれば誰でも利用可能
  • カスタマイズ自由:結合順序や追加機能を自分好みに改良できる
  • オフライン完結:ファイルを外部に送信する必要がなく、セキュリティ面で安心
  • 軽快な処理速度:オンラインサービスのようにアップロード時間を待つ必要がなく、ローカル環境で即座に結合処理が可能

実際に、合計50MB(PDF×3枚+高解像度画像×5枚)を結合してみたところ、処理時間は約4秒で完了しました。
一方、同じファイルをオンラインサービスにアップロードした場合は、回線速度にも左右されますが30秒以上かかりました。
この差は業務効率に直結し、大量のファイルを扱うシーンでは特に大きなメリットとなります。

もちろんAdobe Acrobatのような市販ソフトにはページ編集やOCRなどの高度な機能がありますが、「複数ファイルをシンプルにまとめたい」用途に限定すれば、自作Pythonツールのほうが無料・高速・安全に処理できるのが強みです。

まとめ

今回はPythonとChatGPTを活用して、PDFと画像を一括で結合できるGUIツールを作成しました。
市販ソフトの代わりに自作ツールを使うことで、コストをかけずに業務効率を改善できます。

特に今回の開発ではChatGPTを「プログラミングの相棒」として活用しました。
実装中にエラーが出たときも、ChatGPTに聞いてすぐ修正方法が分かり、
さらに「ドラッグ&ドロップ対応」「順番の入れ替え機能」などの改良も自然な会話の流れで追加できました。

このように、ChatGPTを取り入れることで、初心者でも試行錯誤しながら実用的なツールを作り上げる体験が可能になります。
ぜひ皆さんも、自分のニーズに合わせたPDF管理ツールを作り、日常業務に役立ててみてください。

AIブロガー
筆者:yuki
Python未経験からAIと対話しながらコード作成。副業×自動化×プログラミングの可能性を模索中。 ▷詳細プロフィールはこちら
RELATED POST