PDF スクショ自動化 画像(JPG,PNG,TIFFなど)

Pythonで高機能スクリーンショット自動化ツール:簡単設定で効率アップ!

概要

今回は、Pythonを使って開発した高機能スクリーンショット自動化ツールをご紹介します。このツールを使えば、指定した間隔で自動的にスクリーンショットを撮影し、保存することができます。デフォルトではディスプレイ1の全画面を対象としていますが、カスタム範囲の指定も可能です。SEO、ウェブデザイン、ソフトウェアテストなど、様々な分野で活用できる便利なツールです。

使用例

  • ウェブサイトの経時変化の記録
  • ソフトウェアのテスト過程の自動記録
  • オンライン講義やウェビナーの内容キャプチャ
  • 長時間にわたるプロセスやアニメーションの記録

インストール方法

  1. Pythonがインストールされていることを確認します(バージョン3.6以上推奨)。
  2. 以下のコマンドで必要なライブラリをインストールします:
pip install pyautogui Pillow
  1. 後述のプログラムコードをPythonファイル(例:screenshot_tool.py)として保存します。

使用手順

  1. プログラムを実行すると、GUIウィンドウが表示されます。
  2. スクリーンショットの間隔(秒)を入力します。
  3. 必要に応じて「範囲を選択」ボタンをクリックし、カスタム範囲を指定します。
  4. 保存先ディレクトリを選択します(デフォルトはユーザーのPicturesフォルダ内)。
  5. 画像フォーマット(PNGまたはJPEG)を選択します。
  6. 「開始」ボタンをクリックしてスクリーンショットの自動化を開始します。
  7. プレビューウィンドウで最新のスクリーンショットを確認できます。
  8. 「停止」ボタンをクリックして自動化を停止します。

注意点

  • 大量のスクリーンショットを長時間にわたって撮影する場合、ストレージ容量に注意してください。
  • 高解像度や大きなサイズでの頻繁な撮影は、システムのパフォーマンスに影響を与える可能性があります。
  • プライバシーや著作権に配慮し、適切な範囲でのみ使用してください。
  • マルチディスプレイ環境では、現在はディスプレイ1のみを対象としています。

プログラム

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import pyautogui
import threading
import time
from datetime import datetime
import os
from PIL import Image, ImageTk

class ScreenshotApp:
    def __init__(self, master):
        self.master = master
        self.master.title("スクリーンショット自動化")
        self.master.geometry("400x500")

        self.screenshot_thread = None
        self.is_running = False
        self.save_directory = os.path.join(os.path.expanduser("~"), "Pictures", "Screenshots")
        self.image_format = "png"

        # ディスプレイ1の情報を取得
        self.screen_width, self.screen_height = pyautogui.size()
        self.x1, self.y1, self.x2, self.y2 = 0, 0, self.screen_width, self.screen_height

        self.create_widgets()

    def create_widgets(self):
        # 間隔指定
        ttk.Label(self.master, text="スクリーンショット間隔(秒):").pack(pady=5)
        self.interval_entry = ttk.Entry(self.master)
        self.interval_entry.insert(0, "5")
        self.interval_entry.pack(pady=5)

        # 範囲指定ボタン
        self.select_area_button = ttk.Button(self.master, text="範囲を選択", command=self.start_area_selection)
        self.select_area_button.pack(pady=5)

        # 範囲表示
        self.area_label = ttk.Label(self.master, text=f"選択範囲: {self.screen_width}x{self.screen_height}")
        self.area_label.pack(pady=5)

        # 保存先ディレクトリ選択
        ttk.Button(self.master, text="保存先を選択", command=self.select_save_directory).pack(pady=5)
        self.directory_label = ttk.Label(self.master, text=f"保存先: {self.save_directory}")
        self.directory_label.pack(pady=5)

        # 画像フォーマット選択
        ttk.Label(self.master, text="画像フォーマット:").pack(pady=5)
        self.format_var = tk.StringVar(value="png")
        ttk.Radiobutton(self.master, text="PNG", variable=self.format_var, value="png").pack()
        ttk.Radiobutton(self.master, text="JPG", variable=self.format_var, value="jpg").pack()

        # 開始ボタン
        self.start_button = ttk.Button(self.master, text="開始", command=self.start_screenshot)
        self.start_button.pack(pady=5)

        # 停止ボタン
        self.stop_button = ttk.Button(self.master, text="停止", command=self.stop_screenshot, state=tk.DISABLED)
        self.stop_button.pack(pady=5)

        # プレビュー用のキャンバス
        self.preview_canvas = tk.Canvas(self.master, width=300, height=200)
        self.preview_canvas.pack(pady=10)

    def start_area_selection(self):
        self.master.iconify()
        self.selection_window = tk.Toplevel(self.master)
        self.selection_window.attributes('-fullscreen', True, '-alpha', 0.3)
        self.selection_window.configure(background='grey')

        # Canvasを作成
        self.canvas = tk.Canvas(self.selection_window, highlightthickness=0)
        self.canvas.pack(fill=tk.BOTH, expand=True)

        self.canvas.bind("<ButtonPress-1>", self.on_press)
        self.canvas.bind("<B1-Motion>", self.on_drag)
        self.canvas.bind("<ButtonRelease-1>", self.on_release)

        self.rect = None
        self.start_x = None
        self.start_y = None

    def on_press(self, event):
        self.start_x = self.selection_window.winfo_pointerx() - self.selection_window.winfo_rootx()
        self.start_y = self.selection_window.winfo_pointery() - self.selection_window.winfo_rooty()
        self.rect = self.canvas.create_rectangle(self.start_x, self.start_y, self.start_x, self.start_y, outline='red')

    def on_drag(self, event):
        cur_x = self.selection_window.winfo_pointerx() - self.selection_window.winfo_rootx()
        cur_y = self.selection_window.winfo_pointery() - self.selection_window.winfo_rooty()
        self.canvas.coords(self.rect, self.start_x, self.start_y, cur_x, cur_y)

    def on_release(self, event):
        self.x1 = max(0, min(self.start_x, self.screen_width))
        self.y1 = max(0, min(self.start_y, self.screen_height))
        self.x2 = max(0, min(event.x_root, self.screen_width))
        self.y2 = max(0, min(event.y_root, self.screen_height))
        self.selection_window.destroy()
        self.master.deiconify()
        self.update_area_label()

    def update_area_label(self):
        width = abs(self.x2 - self.x1)
        height = abs(self.y2 - self.y1)
        self.area_label.config(text=f"選択範囲: {width}x{height}")

    def select_save_directory(self):
        directory = filedialog.askdirectory(initialdir=self.save_directory)
        if directory:
            self.save_directory = directory
            self.directory_label.config(text=f"保存先: {self.save_directory}")

    def start_screenshot(self):
        if not self.is_running:
            try:
                interval = float(self.interval_entry.get())
                if interval <= 0:
                    raise ValueError
            except ValueError:
                messagebox.showerror("エラー", "有効な間隔を入力してください")
                return

            self.is_running = True
            self.start_button.config(state=tk.DISABLED)
            self.stop_button.config(state=tk.NORMAL)
            self.select_area_button.config(state=tk.DISABLED)

            self.image_format = self.format_var.get()
            self.screenshot_thread = threading.Thread(target=self.take_screenshots, args=(interval,))
            self.screenshot_thread.start()

    def stop_screenshot(self):
        self.is_running = False
        self.start_button.config(state=tk.NORMAL)
        self.stop_button.config(state=tk.DISABLED)
        self.select_area_button.config(state=tk.NORMAL)

    def take_screenshots(self, interval):
        if not os.path.exists(self.save_directory):
            os.makedirs(self.save_directory)

        while self.is_running:
            current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
            left = max(0, min(self.x1, self.x2))
            top = max(0, min(self.y1, self.y2))
            width = min(abs(self.x2 - self.x1), self.screen_width - left)
            height = min(abs(self.y2 - self.y1), self.screen_height - top)
            
            screenshot = pyautogui.screenshot(region=(left, top, width, height))
            file_path = os.path.join(self.save_directory, f"screenshot_{current_time}.{self.image_format}")
            screenshot.save(file_path)
            self.update_preview(screenshot)
            time.sleep(interval)

    def update_preview(self, screenshot):
        preview = screenshot.copy()
        preview.thumbnail((300, 200))
        photo = ImageTk.PhotoImage(preview)
        self.preview_canvas.delete("all")
        self.preview_canvas.create_image(150, 100, image=photo)
        self.preview_canvas.image = photo

if __name__ == "__main__":
    root = tk.Tk()
    app = ScreenshotApp(root)
    root.mainloop()

あるいは、下のテキストファイルをダウンロードし、「.txt」を「.py」に変えることでそのまま使えます。

まとめ

この高機能スクリーンショット自動化ツールを使えば、様々なシーンで効率的にスクリーンショットを撮影・管理することができます。Pythonの強力な機能とシンプルなGUIを組み合わせることで、技術者からビジネスユーザーまで幅広い方々に活用いただけるツールとなっています。ぜひ、あなたの作業フローに取り入れて、生産性向上にお役立てください!

キーワード:Python、スクリーンショット、自動化、GUI、生産性向上、ツール開発

-PDF, スクショ自動化, 画像(JPG,PNG,TIFFなど)