「複数のPDFや画像をまとめて1つのファイルにしたい」──そう思ったことはありませんか?

市販ソフトでも可能ですが、無料で使えるPythonを活用すれば、用途にぴったりのツールを自作できます。

この記事では、ChatGPTでコードを生成・改良しながら、PDF+画像をまとめて結合できるGUIツールを作った手順を紹介します。

  • 画像(PNG/JPG等)+PDFを混在して1つのPDFへ結合
  • ドラッグ&ドロップで追加 → 順番を入れ替えて変換
  • 配布用にEXE化(PyInstaller)も可能

実際に私もブログ記事や業務資料の整理で使っており、ドラッグ&ドロップで結合できるので作業効率がかなり上がりました。

必要なライブラリ

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

💡 補足:以下で一括インストールできます。

pip install pillow pymupdf tkinterdnd2

TkinterはPython標準に含まれているため、追加インストールは不要です。

PyMuPDFはPDFと画像を統合的に扱える高速ライブラリで、結合系の用途でも安定しやすいのが強みです。

完成イメージ(できること)

  • 画像/PDFをリストに追加(ドラッグ&ドロップ対応)
  • ↑↓で順番を変更
  • 「PDFに変換」で一括結合して1つのPDFを出力

Pythonコード(完成版)

以下が完成版のコードです。ChatGPTで生成→改良しながら、実用レベルのGUIアプリとして仕上げました。

※重要:元コードにあった os.path.splitext(path)[1] の「1」が全角だとエラーになるので、[1](半角)に直しています。

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

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()

            if ext in [".png", ".jpg", ".jpeg", ".bmp", ".tiff"]:
                img = Image.open(path)
                if img.mode != "RGB":
                    img = img.convert("RGB")

                # tempファイル名の衝突を避ける
                with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as tmp:
                    temp_path = tmp.name

                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の分解(ページごとの抽出)
  • 画像サイズ・向きの自動調整
  • 大量ファイル対応のバッチ処理
  • 圧縮(容量を小さくして共有しやすく)
ここから先、改良が面倒なら「外注で最短」もアリです
「Macでも確実に動かしたい」「EXE化して配布したい」「画像の向き/サイズを自動補正したい」など、
“一歩先の実用化”は手間が増えます。
その場合は 仕様だけ渡して丸投げ が一番早いです。
  • 大量ファイルでも落ちないよう最適化
  • 圧縮・ページ番号・余白・サイズ統一などの追加仕様
  • 社内配布用(EXE化 / アイコン / 画面整備)
見積もりが速くなる依頼テンプレ:
①入力例(PDF/画像) ②出力イメージ ③結合順ルール ④動作環境(Win/Mac) ⑤納期
依頼文に迷ったら → 【コピペOK】Python依頼文テンプレはこちら
※テンプレのまま投げるだけでも、提案の質と見積もり精度が上がります。

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

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

pyinstaller your_script.py --onefile

EXE化すると、タスクバーに固定したり、他人に配布したりすることも可能になります。

詳しい手順は以下の記事で解説しています。

Pythonを.exeに変換する方法|PyInstallerで配布用実行ファイルを作成する手順

補足情報(詰まりやすいポイント)

  • 環境依存:Windowsは動きやすい一方、Mac/LinuxはD&D周りで追加設定が必要な場合があります。
  • 処理速度:高解像度画像が多いと時間がかかるため、将来的に圧縮機能を入れると便利です。
  • 代替ライブラリ:PyPDF2でも結合は可能ですが、画像混在や実用化の観点ではPyMuPDFが扱いやすいです。

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

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

  • 市販ソフト:有料ライセンスが必要(サブスク費用が高め)
  • オンライン:アップロード容量や回数に制限がある
  • セキュリティ:機密ファイルをアップロードするリスク

一方、Python自作ツールは以下が強みです。

  • 完全無料:Python環境があれば利用可能
  • カスタマイズ自由:結合順序・追加機能を自分好みに拡張
  • オフライン完結:ファイルを外部に送らないので安心
  • 待ち時間が少ない:アップロード不要でローカル即処理

※処理時間の実測値は環境や画像解像度で変わるため、目安として捉えてください。

まとめ

今回はPythonとChatGPTを活用して、PDFと画像を一括で結合できるGUIツールを作成しました。

市販ソフトの代わりに自作ツールを使うことで、コストをかけずに業務効率を改善できます。

特に今回の開発では、ChatGPTを「プログラミングの相棒」として活用し、エラー修正や機能追加を会話ベースで進められました。

次の一手:改良して「実務で使える形」に寄せたいなら、
・圧縮(容量削減)
・画像の向き/サイズ自動補正
・EXE化&配布用UI調整
このあたりが伸びしろです。

「作る時間がない」なら、外注で一気に片付けるのもアリ
仕様を軽くまとめて相談→提案比較するだけでも、最短ルートが見えます。

ココナラで見積もり相談する →