webp画像への自動変換ツールを制作しました

完成したコード

まだコメント表示のロジックがイマイチであったり、photoshopから書き出した画像に対してエラーが出てしまうなどのバグが残っています。

import os
import time
import json
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from PIL import Image

# 更新日時の記録用ファイル
TIMESTAMP_FILE = "timestamps.json"

def load_timestamps():
    """JSONファイルから更新日時をロード"""
    if os.path.exists(TIMESTAMP_FILE):
        with open(TIMESTAMP_FILE, "r", encoding="utf-8") as file:
            return json.load(file)
    return {}

def save_timestamps(timestamps):
    """更新日時をJSONファイルに保存"""
    with open(TIMESTAMP_FILE, "w", encoding="utf-8") as file:
        json.dump(timestamps, file, indent=4, ensure_ascii=False)

class ImageConversionHandler(FileSystemEventHandler):
    def __init__(self):
        self.timestamps = load_timestamps()

    def on_created(self, event):
        # 対象がファイルかつ対応する拡張子の場合のみ処理
        if not event.is_directory and event.src_path.lower().endswith(('jpg', 'jpeg', 'png', 'gif')):
            # 追加: ディレイを設定
            time.sleep(5)
            if os.path.exists(event.src_path):  # ファイルが存在することを確認
                self.convert_to_webp(event.src_path)  # ここで convert_to_webp メソッドを呼び出している

    def convert_to_webp(self, img_path):  # ここで convert_to_webp メソッドを定義
        # 画像ファイルのあるフォルダパスを取得
        parent_folder = os.path.dirname(img_path)
        # 出力先フォルダを指定(convertWEBPフォルダを作成)
        output_folder = os.path.join(parent_folder, "converted_webp")
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)

        # 出力ファイルのパスを作成
        file_name = os.path.basename(img_path)
        base_name, _ = os.path.splitext(file_name)
        webp_path = os.path.join(output_folder, base_name + '.webp')

        try:
            # 元画像の更新日時を取得
            img_mtime = os.path.getmtime(img_path)

            # 過去の更新日時を取得(なければ処理実行)
            last_mtime = self.timestamps.get(img_path)
            if last_mtime and last_mtime >= img_mtime:
                print(f"スキップ: {img_path} は更新されていません。")
                return

            with Image.open(img_path) as img:
                img = img.convert("RGB")  # WebPはRGBフォーマットが必要
                img.save(webp_path, 'webp')  # .webpファイルを保存
                print(f"変換成功: {img_path} -> {webp_path}")

                # 更新日時を記録
                self.timestamps[img_path] = img_mtime
                save_timestamps(self.timestamps)

                # 画像が初めて追加された場合のメッセージを表示
                if not last_mtime:
                    print(f"追加されました: {img_path} が初めて変換されました。")

        except (IOError, ValueError, FileNotFoundError) as e:
            print(f"変換失敗: {img_path}. エラー: {e}")

def monitor_folder(input_folder):
    event_handler = ImageConversionHandler()
    observer = Observer()
    observer.schedule(event_handler, input_folder, recursive=True)  # サブフォルダも監視
    observer.start()
    print(f"フォルダ監視中: {input_folder}")

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
        print("\n監視を停止しました。")
    observer.join()

def restart_script():
    """スクリプトを再起動"""
    print("エラーが発生しました。スクリプトを再起動します...")
    python = sys.executable
    os.execl(python, python, *sys.argv)

def main():
    # 実行時のカレントディレクトリを取得
    input_folder = os.getcwd()
    print(f"監視フォルダ: {input_folder}")

    if not os.path.exists(input_folder):
        print(f"入力フォルダが見つかりません: {input_folder}")
        return

    try:
        monitor_folder(input_folder)
    except Exception as e:
        print(f"エラー: {e}")
        restart_script()

if __name__ == "__main__":
    while True:
        try:
            main()
        except Exception as e:
            print(f"メインループでエラーが発生しました: {e}")
            time.sleep(5)  # 再試行前に少し待機
pythonウェブサイト
スポンサーリンク

コメント

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