最近学习python想用自己喜欢的图片做图标还得去网站上转换,突发奇想不如自己做一个转换工具,
该工具支持6种主流图片格式进行互转,转为ICO格式时需要强制选择分辨率。
附上源码和软件,希望大家喜欢。
https://thebzk.lanzn.com/inuVD2pucl9a
密码:en0p
[Python] - import tkinter as tk
- import ttkbootstrap as ttk
- from ttkbootstrap.constants import *
- from tkinter import filedialog, messagebox
- from PIL import Image, ImageTk, UnidentifiedImageError
- formats = {
- "ICO": ".ico",
- "PNG": ".png",
- "JPEG": ".jpg",
- "GIF": ".gif",
- "BMP": ".bmp",
- "TIFF": ".tiff"
- }
- ico_resolutions = {
- "16x16": (16, 16),
- "24x24": (24, 24),
- "32x32": (32, 32),
- "48x48": (48, 48),
- "64x64": (64, 64),
- "128x128": (128, 128),
- "256x256": (256, 256)
- }
- class ImageConverterGUI:
- def __init__(self, master):
- self.master = master
- self.master.title("图片格式转换工具 v1.0 — Thebzk")
- self.master.geometry("600x700")
- self.master.resizable(False, False)
- main_frame = ttk.Frame(self.master, padding=20)
- main_frame.pack(fill=tk.BOTH, expand=True)
- input_frame = ttk.Labelframe(main_frame, text="输入文件", padding=10)
- input_frame.pack(fill=tk.X, pady=5)
- input_grid = ttk.Frame(input_frame)
- input_grid.pack(fill=tk.X)
- ttk.Label(input_grid, text="选择图片文件:").grid(row=0, column=0, padx=5)
- self.input_var = tk.StringVar()
- ttk.Entry(input_grid, textvariable=self.input_var, width=40).grid(row=0, column=1, padx=5)
- ttk.Button(
- input_grid,
- text="选择文件",
- command=self.choose_input_file,
- bootstyle="primary",
- width=12
- ).grid(row=0, column=2, padx=5)
- settings_frame = ttk.Labelframe(main_frame, text="转换设置", padding=10)
- settings_frame.pack(fill=tk.X, pady=5)
- settings_grid = ttk.Frame(settings_frame)
- settings_grid.pack(fill=tk.X)
- ttk.Label(settings_grid, text="输出格式:").grid(row=0, column=0, padx=5)
- self.format_var = tk.StringVar(value='')
- format_combobox = ttk.Combobox(
- settings_grid,
- textvariable=self.format_var,
- values=list(formats.keys()),
- bootstyle="primary",
- state="readonly",
- width=12
- )
- format_combobox.grid(row=0, column=1, padx=5)
- self.ico_resolution_var = tk.StringVar(value='')
- self.ico_resolution_box = ttk.Combobox(
- settings_grid,
- textvariable=self.ico_resolution_var,
- values=list(ico_resolutions.keys()),
- bootstyle="primary",
- state="disabled",
- width=12
- )
- self.ico_resolution_box.grid(row=0, column=2, padx=5)
- format_combobox.bind("", self.toggle_ico_resolution)
- ttk.Button(
- settings_grid,
- text="开始转换",
- command=self.convert,
- bootstyle="success",
- width=12
- ).grid(row=0, column=3, padx=5)
- preview_frame = ttk.Labelframe(main_frame, text="图片预览", padding=10)
- preview_frame.pack(fill=tk.BOTH, expand=True, pady=5)
- self.preview_canvas = ttk.Canvas(preview_frame, bg='#f8f9fa')
- self.preview_canvas.pack(fill=tk.BOTH, expand=True)
- self.preview_image = None
- log_frame = ttk.Labelframe(main_frame, text="操作日志", padding=10)
- log_frame.pack(fill=tk.X, pady=5)
- self.log_area = ttk.Text(
- log_frame,
- wrap=tk.WORD,
- font=("Consolas", 9),
- height=22,
- bg="#f8f9fa",
- fg="#495057"
- )
- self.log_area.pack(fill=tk.BOTH)
- def toggle_ico_resolution(self, event):
- """切换ICO分辨率下拉框状态"""
- if self.format_var.get() == "ICO":
- self.ico_resolution_box.configure(state="readonly")
- else:
- self.ico_resolution_box.configure(state="disabled")
- def choose_input_file(self):
- file_path = filedialog.askopenfilename(
- filetypes=[("图片文件", "*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.tiff")]
- )
- if file_path:
- self.input_var.set(file_path)
- self.show_preview(file_path)
- def show_preview(self, file_path):
- try:
- self.preview_canvas.delete("all")
- img = Image.open(file_path)
- canvas_width = self.preview_canvas.winfo_width() - 20
- canvas_height = self.preview_canvas.winfo_height() - 20
- img_ratio = img.width / img.height
- canvas_ratio = canvas_width / canvas_height
- if img_ratio > canvas_ratio:
- new_width = min(img.width, canvas_width)
- new_height = int(new_width / img_ratio)
- else:
- new_height = min(img.height, canvas_height)
- new_width = int(new_height * img_ratio)
- img = img.resize((new_width, new_height), Image.LANCZOS)
- self.preview_image = ImageTk.PhotoImage(img)
- x = (self.preview_canvas.winfo_width() - new_width) // 2
- y = (self.preview_canvas.winfo_height() - new_height) // 2
- self.preview_canvas.create_image(x, y, anchor=tk.NW, image=self.preview_image)
- except Exception as e:
- messagebox.showerror("错误", f"预览失败: {str(e)}")
- def convert(self):
- input_path = self.input_var.get()
- output_format = self.format_var.get()
- ico_resolution = self.ico_resolution_var.get()
- if not input_path:
- messagebox.showwarning("提示", "请选择输入文件!")
- return
- if not output_format:
- messagebox.showwarning("提示", "请选择输出格式!")
- return
- output_dir = filedialog.askdirectory(title="选择输出目录")
- if not output_dir:
- messagebox.showwarning("提示", "请选择输出目录!")
- return
- try:
- img = Image.open(input_path)
- format_lower = output_format.lower()
- if format_lower == 'ico':
- if not ico_resolution:
- messagebox.showwarning("提示", "请选择ICO分辨率!")
- return
- sizes = [ico_resolutions[ico_resolution]]
- img.save(f"{output_dir}/output.{formats[output_format]}", format_lower.upper(), sizes=sizes)
- else:
- img.save(f"{output_dir}/output.{formats[output_format]}", format_lower.upper())
- messagebox.showinfo("成功", f"图片已成功转换并保存到 {output_dir}/output.{formats[output_format]}")
- self.log_message(f"成功保存到 {output_dir}/output.{formats[output_format]}")
- except UnidentifiedImageError:
- messagebox.showerror("错误", "无法识别图片格式!")
- self.log_message("无法识别图片格式!", level="ERROR")
- except Exception as e:
- messagebox.showerror("错误", f"转换失败: {str(e)}")
- self.log_message(f"转换失败: {str(e)}", level="ERROR")
- def log_message(self, message, level="INFO"):
- self.log_area.insert(tk.END, f"[{level}] {message}\n")
- self.log_area.see(tk.END)
- def main():
- root = ttk.Window(themename="cosmo")
- app = ImageConverterGUI(root)
- root.mainloop()
- if __name__ == "__main__":
- main()
复制代码
 |