以下は『断影結晶符転』のソースコード全文です:
from PIL import Image, ImageTk
import tkinter as tk
from tkinter import filedialog, messagebox
import os
from datetime import datetime
# 使用可能なサイズ
AVAILABLE_SIZES = [16, 32, 48, 64, 128, 256]
class IconConverterApp:
def __init__(self, root):
self.root = root
self.root.title("ICO作成ツール - 断影結晶符転")
self.root.geometry("500x500")
self.root.resizable(False, False)
self.image_path = None
self.img_preview_label = None
self.check_vars = {}
self.create_widgets()
def create_widgets(self):
# 画像選択ボタン
tk.Button(self.root, text="画像を選択", command=self.select_image, font=("Arial", 12)).pack(pady=10)
# プレビュー用キャンバス
self.preview_canvas = tk.Canvas(self.root, width=256, height=256, bg="gray90")
self.preview_canvas.pack(pady=10)
# サイズ選択チェックボックス
tk.Label(self.root, text="作成するサイズを選択:", font=("Arial", 11)).pack()
self.check_vars = {size: tk.BooleanVar(value=True) for size in AVAILABLE_SIZES}
check_frame = tk.Frame(self.root)
check_frame.pack(pady=5)
for size in AVAILABLE_SIZES:
cb = tk.Checkbutton(check_frame, text=f"{size}x{size}", variable=self.check_vars[size])
cb.pack(side=tk.LEFT, padx=5)
# 実行ボタン
tk.Button(self.root, text="実行", command=self.create_ico, font=("Arial", 12)).pack(pady=15)
def select_image(self):
path = filedialog.askopenfilename(
title="画像ファイルを選択してください",
filetypes=[("画像ファイル", "*.png;*.jpg;*.jpeg;*.bmp")]
)
if not path:
return
try:
img = Image.open(path)
except Exception as e:
messagebox.showerror("エラー", f"画像の読み込みに失敗しました:\n{e}")
return
self.image_path = path
self.display_preview(img)
if img.width != img.height:
messagebox.showwarning("警告", "選択された画像は正方形ではありません。\n歪んだアイコンになる可能性があります。")
def display_preview(self, img):
img_resized = img.copy().resize((256, 256), Image.LANCZOS)
self.tk_preview_image = ImageTk.PhotoImage(img_resized)
self.preview_canvas.delete("all")
self.preview_canvas.create_image(128, 128, image=self.tk_preview_image)
def create_ico(self):
if not self.image_path:
messagebox.showwarning("警告", "まず画像を選択してください。")
return
selected_sizes = [size for size, var in self.check_vars.items() if var.get()]
if not selected_sizes:
messagebox.showwarning("警告", "少なくとも1つのサイズを選択してください。")
return
try:
img = Image.open(self.image_path)
except Exception as e:
messagebox.showerror("エラー", f"画像の再読み込みに失敗しました:\n{e}")
return
# 保存ファイル名と場所
base = os.path.splitext(os.path.basename(self.image_path))[0]
now_str = datetime.now().strftime("%Y%m%d-%H%M%S")
save_path = os.path.join(os.path.dirname(self.image_path), f"{base}-{now_str}.ico")
try:
img.save(save_path, format="ICO", sizes=[(s, s) for s in selected_sizes])
messagebox.showinfo("保存完了", f"アイコンを保存しました:\n{save_path}")
except Exception as e:
messagebox.showerror("保存失敗", f"ICOファイルの保存に失敗しました:\n{e}")
# アプリ起動
if __name__ == "__main__":
root = tk.Tk()
app = IconConverterApp(root)
root.mainloop()