Pythonでタスクトレイ常駐|スクリーンショットを取得するプログラムを作る!

Python

Pythonでスクリーンショットを取得するには?

業務プログラムを作成し運用をしているとシステムの操作マニュアル作成時などで自動的にスクリーンショットを取得したい場合があります。他にも以下のようなシチュエーションで利用の機会があります。

利用シチュエーション

システムの監視
サーバーやネットワークの管理画面で異常が検出された際に、証拠としてスクリーンショットを自動的に保存する。

自動テスト
ソフトウェア開発において、自動テストの結果を記録するために、テスト実行時の画面をスクリーンショットで取得する。

ゲームプレイの記録
ゲーム内で特定のイベントが発生した時を漏らさずに(例えば、ハイスコアを更新した時)に自動でスクリーンショットを取得し、記録する。

セキュリティ
不正アクセスや異常な動作が検出された際に、証拠としてスクリーンショットを自動で取得する。

リアルタイム情報の記録
株価やニュースサイトのリアルタイム情報を定期的にスクリーンショットで記録し、後で分析や参照を行う。

プログラムは苦手だからexeファイルが欲しいという方は本ページの「最後に」を参照ください。

スクリーンショットを自動取得するサンプルコード

プログラムを実行するとタスクトレイに常駐して、タスクトレイからExitするまで自動的にスクリーンショットを撮り続けるサンプルを紹介します。

import datetime
# datetime 日付や時刻を操作
# このプログラムでは、ファイル名の生成に日時を使用します。

import time
# time 時間に関連する操作
# このプログラムでは、スクリーンショットの間隔を制御するために sleep 関数を使用します。

import threading
# threading スレッドベースの並行処理をサポート
# このプログラムでは、バックグラウンドでスクリーンショットを取得するために別のスレッドを起動します。

# pip install pillow
from PIL import Image, ImageDraw
# PIL(Python Imaging Library) 画像処理機能
# このプログラムでは、システムトレイアイコンを作成するために Image と ImageDraw クラスを使用します。

# pip install pystray
from pystray import MenuItem as item
import pystray
# pystray システムトレイアイコンを作成し管理
# このプログラムでは、システムトレイにアイコンを表示し、そのアイコンに対するインタラクションを処理します。

# pip install pyautogui
import pyautogui
# pyautogui プログラムでマウスやキーボードを制御
# このプログラムでは、スクリーンショットを取得するために使用されます。


def create_icon_image():
    """
    タスクトレイアイコン用のイメージを作成する関数。
    この関数は4色の四角形を使用してアイコンを作成します。
    
    Returns:
        Image: 生成されたイメージオブジェクト。
    """
    # アイコンのサイズと色を定義
    width, height = 64, 64
    colors = [(255, 128, 128), (128, 255, 128), (128, 128, 255), (255, 255, 128)]  # 赤、緑、青、黄色

    image = Image.new('RGB', (width, height))
    dc = ImageDraw.Draw(image)

    # 各象限に色を塗る
    dc.rectangle([0, 0, width // 2, height // 2], fill=colors[0])  # 左上
    dc.rectangle([width // 2, 0, width, height // 2], fill=colors[1])  # 右上
    dc.rectangle([0, height // 2, width // 2, height], fill=colors[2])  # 左下
    dc.rectangle([width // 2, height // 2, width, height], fill=colors[3])  # 右下

    return image


def capture_screen(interval=5, format='png'):
    """
    一定間隔で画面をキャプチャして指定された形式で保存する関数。
    別スレッドで実行される。

    Args:
        interval (int): 画面キャプチャの間隔(秒)。デフォルトは5秒。
        format (str): 保存する画像の形式。'png', 'jpg', 'gif', 'bmp', 'tiff', 'webp' が利用可能。
    """
    format = format.lower()
    if format not in ['png', 'jpg', 'gif', 'bmp', 'tiff', 'webp']:
        raise ValueError("Unsupported format: {}".format(format))

    while not stop_event.is_set():
        timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f"{timestamp}.{format}"
        screenshot = pyautogui.screenshot()
        if format == 'jpg':
            screenshot.save(filename, 'JPEG', quality=95)
        else:
            screenshot.save(filename, format.upper())
        print(f"{filename} が保存されました。")
        time.sleep(interval)


def screencapture_exit(icon):
    """
    終了メニュー項目が選択されたときに実行される関数。
    
    Args:
        icon: アイコンのインスタンス。
        item: メニューアイテムのインスタンス。
    """
    icon.stop()
    stop_event.set()




##############################################################
# 関数のテスト
if __name__ == "__main__":

    # スクリーンショットのキャプチャを制御するためのイベント
    stop_event = threading.Event()

    # メニュー項目を定義
    menu = (item('Exit', screencapture_exit),)

    # アイコンを作成し、右クリックメニューを設定
    #引数1 "screencapture": これはアイコンの内部名です。この名前は、システムトレイに表示されるわけではありませんが、
    #    プログラム内部でアイコンを識別するために使用されます。
    #    この名前を変更してもユーザーインターフェイスには影響しませんが、コード内でアイコンを参照する場合はこの名前を使用します。
    #引数2 create_icon_image(): アイコンとして表示される画像を生成する関数です。この関数は上記のコードに定義されており、64x64ピクセルの簡単な色付き四角形の画像を生成しています。
    #引数3 "Screen Capture": システムトレイアイコンにカーソルを合わせたときに表示されるツールチップテキストです。
    #引数4 menu: アイコンを右クリックしたときに表示されるコンテキストメニューです。この例では、「Exit」というメニュー項目があり、選択するとscreencapture_exit関数が呼び出されます。
    icon = pystray.Icon("screencapture", create_icon_image(), "Screen Capture", menu)

    # スクリーンショット取得用のスレッドを開始 5秒間隔でpngファイルへ保存します。
    capture_thread = threading.Thread(target=capture_screen)
    # 引数を渡して 秒数の変更とファイルの拡張子を変更したい場合には以下を参考にしてください。
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'png'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'jpg'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'gif'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'bmp'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'tiff'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'webp'))
    capture_thread.start()

    # アイコンを実行
    icon.run()

    # アイコンの実行が終了したらスレッドを終了
    capture_thread.join()

pillow、pystray、pyautoguiを使用していますので事前にモジュールをインストールする必要があります。以下を参照してインストールしてください。

pip install pillow
pip install pystray
pip install pyautogui

実行結果

実行すると以下のようにアイコンがタスクトレイに常駐します。

右クリックしてExitで終了します。

スクリーンショットされたファイルは、プログラムが実行されたフォルダに年月日と時間分秒で保存されます。

異なる拡張子でも保存が可能ですので、プログラムの以下コメントを調整してみてください。

    # スクリーンショット取得用のスレッドを開始 5秒間隔でpngファイルへ保存します。
    capture_thread = threading.Thread(target=capture_screen)
    # 引数を渡して 秒数の変更とファイルの拡張子を変更したい場合には以下を参考にしてください。
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'png'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'jpg'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'gif'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'bmp'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'tiff'))
    #capture_thread = threading.Thread(target=capture_screen, args=(1, 'webp'))
    capture_thread.start()

プログラムの動作を変えたい場合

このプログラムでは、スクリーンショットを5秒間隔pngファイル取得をデフォルトとして動作させています。iniファイル読み込み等で柔軟に対処できるのでこちらの組み込みも検討してみてください。

exe化したい場合

別の方にプログラムを動かしてもらいたい場合には、exe化して対応する方に渡すのがよいとおもいます。
その場合にはこちらを参照してexe化してください。

最後に

以上がPythonでスクリーンショットプログラムをタスクトレイに常駐させ自動取得する方法です。

マニュアルを作成したい場合などで自動的にスクリーンショットを取得したい場合に活用してみてはいかがでしょうか。

また本プログラムのexeファイルもダウンロードできますので動作確認してみたい方は活用ください。
※zipファイルで圧縮されています。

実行時に「WindowsによってPCが保護されました」と表示される場合にはこちらを参照ください。

コメント

タイトルとURLをコピーしました