画像複製ツール『影写ノ贄』 ソースコード

『影写ノ贄』は、選択した画像を任意の枚数だけ複製するツールです。

>>GUI外観 >>使い方

以下は画像複製ツール『影写ノ贄』のソースコード全文です:


        import os
        import shutil
        import tkinter as tk
        from tkinter import filedialog, messagebox, ttk
        from PIL import Image, ImageTk
        
        # ==============================
        # 複製処理ロジック
        # ==============================
        def duplicate_image(src_path: str, num_copies: int) -> str:
            """
            指定された画像を指定枚数複製し、copyフォルダに格納する。
            Returns: 保存先フォルダのパス
            """
            base_dir = os.path.dirname(src_path)
            filename = os.path.basename(src_path)
            name, ext = os.path.splitext(filename)
        
            copy_dir = os.path.join(base_dir, "copy")
            os.makedirs(copy_dir, exist_ok=True)
        
            for i in range(1, num_copies + 1):
                new_name = f"{name}-{i:02d}{ext}"
                new_path = os.path.join(copy_dir, new_name)
                shutil.copy2(src_path, new_path)
        
            return copy_dir
        
        
        # ==============================
        # GUI制御クラス
        # ==============================
        class ImageCopyApp:
            def __init__(self, master):
                self.master = master
                self.master.title("画像複製ツール - 影写ノ贄")
                self.master.geometry("520x400")
        
                self.img_path = ""
                self.preview_img = None  # 画像プレビュー用
                self._build_interface()
        
            # ------------------------------
            # UI構築
            # ------------------------------
            def _build_interface(self):
                frame = ttk.Frame(self.master, padding=20)
                frame.pack(fill="both", expand=True)
        
                # 画像選択
                ttk.Button(frame, text="画像選択", command=self.select_image).grid(row=0, column=0, sticky="w")
                self.path_label = ttk.Label(frame, text="選択されていません", width=50)
                self.path_label.grid(row=0, column=1, padx=10, sticky="w")
        
                # プレビュー枠
                ttk.Label(frame, text="プレビュー:").grid(row=1, column=0, sticky="nw", pady=(15, 0))
                self.preview_label = ttk.Label(frame, relief="solid", width=40, anchor="center")
                self.preview_label.grid(row=1, column=1, pady=(10, 10))
        
                # 複製枚数
                ttk.Label(frame, text="複製枚数 (2~30):").grid(row=2, column=0, pady=20, sticky="w")
                self.copy_count = tk.Spinbox(frame, from_=2, to=30, width=5)
                self.copy_count.grid(row=2, column=1, sticky="w")
        
                # 実行ボタン
                ttk.Button(frame, text="実行", command=self.execute).grid(row=3, column=0, columnspan=2, pady=20)
        
            # ------------------------------
            # イベントハンドラ
            # ------------------------------
            def select_image(self):
                path = filedialog.askopenfilename(
                    title="画像を選択してください",
                    filetypes=[("画像ファイル", "*.png;*.jpg;*.jpeg;*.bmp;*.gif")]
                )
                if not path:
                    return
        
                self.img_path = path
                self.path_label.config(text=path)
        
                # プレビュー画像表示
                self.show_preview(path)
        
            def show_preview(self, path):
                """選択された画像を縮小して表示"""
                try:
                    img = Image.open(path)
                    img.thumbnail((300, 200))  # 最大サイズ指定
                    self.preview_img = ImageTk.PhotoImage(img)
                    self.preview_label.config(image=self.preview_img, text="")
                except Exception as e:
                    self.preview_label.config(text=f"プレビュー不可\n({e})", image="")
                    self.preview_img = None
        
            def execute(self):
                if not self.img_path:
                    messagebox.showwarning("警告", "画像を選択してください。")
                    return
        
                try:
                    num_copies = int(self.copy_count.get())
                except ValueError:
                    messagebox.showerror("エラー", "複製枚数を正しく入力してください。")
                    return
        
                if not (2 <= num_copies <= 30):
                    messagebox.showerror("エラー", "複製枚数は2~30の範囲で指定してください。")
                    return
        
                confirm = messagebox.askyesno("確認", f"{num_copies}枚の複製を作成しますか?")
                if not confirm:
                    return
        
                try:
                    output_dir = duplicate_image(self.img_path, num_copies)
                    messagebox.showinfo("完了", f"{num_copies}枚の複製を作成しました。\n保存先: {output_dir}")
                except Exception as e:
                    messagebox.showerror("エラー", f"複製中にエラーが発生しました:\n{e}")
        
        
        # ==============================
        # エントリポイント
        # ==============================
        if __name__ == "__main__":
            root = tk.Tk()
            
            ##タイトルバーアイコン表示用
            data = '''R0lGODdhEAAQAIcAAEvc/z7I8y647Ci08zKx4iuz4Cex7ymbySCczx+d2h+a1iKXyx2UySSNuxuPzCGHsxuJvBeFvxeBtxF7thR6sxd5rBJ2rhh1pBFxphB1sBB0rxlvmBBwqBBwphlskA9upQ9roQ5pnxZmjgxjmAxjlw1hlAtbjA1ZhhNXeQ1WgQlTgwZShQdRggpKcwhJdAlIcglHcAtHaghFcAZFcglEagpDZwpCaglAZgo/YAk7Xwg4XQo3Vgg3WAczUgcwTAgvSwYvSwguSQgsRQQuTwkrQgkqQgkpPwkpPggpPggoPQonOwkmOQgnPAgnOgcmOQkjMwgiMgkhMwcjNgMhOQkgLwkfLgcfLQgeKwgdKQocJwkbJggbJgcZJQoYHwkYIQoYHgMYKQkXHgkWHQkWHAcWHwoVGgsUFgkVGQkVGAkUGQkUGAkUFwoTFgsSEwoSEwkSEwsREQsREAoREgoREQkREwkREggVGQgTGAgTFwgSFggRFAcRFgYRGQIRHgwQDgsQDwsQDgwPDAwPCwsPDQsPDA4OCQ0OCg0OCQwOCwwOCgwOCQsODAsOCwsOCgkQEgkQEQoQEAoQDwoQDgkQEAoPDgoPDQkPDwkPDggQEggPDwoODQoODAoOCwkODQ4NBw0NCA0NBwwNCgwNCQwNCAwMCAwMBwwMBgsNCgsNCQsNCAsMCAoNDAoNCwoNCgQLEQQKEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAEAAQAEAI/wBNpWK0aROrVZcoGeTUSlWpUYm6FNmhAwIJAQUSRFhBowqgQ6NOzbmC50wfEQfAWPlRBRIqUYcSDXJzJ0mKDBpicFEjqRHMUqgWPXo0KVMTJ5joDGVVqhSiTU9yQJlyAcCDDTNUCNEi55CgOF+i4CihAAQHCSNgHJmDyBCoT4kaAYLjxksYN5EIhYJ5yJQqRpU0bbKkJ4+lToJRNQVK6UydN688oHBlZ8uYTaRGKRrkiAgWMkAaEBjiQwaTNYMUIWJjxEaQFxUCmFjwgcUNKnAOBTKjZEkPBwMYIDAQwgWPLI0MGfLTRgwSDB0oWJhwQkqZQYkUfTqEiJCbNHxa1BzYg2YOIVGjDHn6JEpRo0aE/vwBxCjRKFGGCgUEADs=''' 
            root.tk.call('wm', 'iconphoto', root._w, tk.PhotoImage(data=data))
            ####
            
            app = ImageCopyApp(root)
            root.mainloop()
    

📦 ダウンロード 🏠 ホームへ