目录
[📥 工具下载](#📥 工具下载)
[🚀 操作步骤(5 步搞定)](#🚀 操作步骤(5 步搞定))
[📋 查看转换结果](#📋 查看转换结果)
[💡 核心特性说明](#💡 核心特性说明)
[📥 前期准备](#📥 前期准备)
[🚀 核心操作步骤(5 步完成转换)](#🚀 核心操作步骤(5 步完成转换))
[💡 关键特性与注意事项](#💡 关键特性与注意事项)
[📂 查看结果](#📂 查看结果)
工具界面


转化结果

工具使用及下载
📥 工具下载
解压密码:xi.ji

🚀 操作步骤(5 步搞定)
-
选择输入图片在「输入选择」区域,点击「选择文件」按钮,从电脑中挑选你想要转换的图片(支持 PNG、JPG、BMP、GIF、TIFF 等格式)。
-
选择输出文件夹在「输出设置」区域,点击「选择」按钮,指定生成的 ICO 文件要保存到哪个文件夹。
-
选择目标格式为 ICO 在「目标格式」下拉菜单中,选择 ICO 选项。此时下方会展开「ICO 尺寸选择」区域。
-
选择 ICO 尺寸
- 常用尺寸:直接勾选你需要的尺寸(如 16x16、32x32、48x48)。
- 自定义尺寸 :如果需要特殊尺寸,在输入框中按格式填写(如
50,50;64,64),多个尺寸用分号分隔。
-
开始转换 点击「开始转换」按钮,工具会自动处理图片,并为每个勾选的尺寸生成独立的 ICO 文件(命名规则:
原文件名_宽x高.ico,例如图标_16x16.ico)。
📋 查看转换结果
- 转换日志:窗口下方的「转换日志」区域会实时显示每个尺寸的生成状态(成功 / 失败),并带时间戳,方便你追踪过程。
- 生成的文件:前往你选择的输出文件夹,就能看到所有生成的 ICO 文件,每个文件对应一个尺寸,且都能被 Windows 正常打开。
💡 核心特性说明
- 智能处理非标准图片:如果你的原图是长方形等非正方形,工具会自动先按比例缩放,再从中心裁剪出正方形区域,保证生成的 ICO 不变形、内容居中。
- 格式兼容:生成的 ICO 文件完全符合 Windows 规范,不会出现「无法打开」的问题。
- 容错机制:如果忘记选择尺寸,工具会自动使用 16x16、32x32、48x48 这三个常用尺寸作为默认值;如果自定义尺寸输入错误,会弹出提示并继续使用勾选的尺寸。

工具源码
pythonimport os import tkinter as tk from tkinter import ttk, filedialog, messagebox from PIL import Image from PIL.Image import UnidentifiedImageError # ====================== 核心转换函数 ====================== def convert_image(input_path, output_path, target_format): try: with Image.open(input_path) as img: if target_format == 'JPEG' and img.mode in ('RGBA', 'P'): background = Image.new('RGB', img.size, (255, 255, 255)) if img.mode == 'RGBA': background.paste(img, mask=img.split()[3]) else: background.paste(img) img = background img.save(output_path, format=target_format) return True, f"转换成功:{os.path.basename(input_path)}" except Exception as e: return False, f"转换失败 {os.path.basename(input_path)}:{str(e)}" def create_single_size_ico(input_path, output_path, size): target_w, target_h = size try: with Image.open(input_path) as img: if img.mode != 'RGBA': img = img.convert('RGBA') scale_factor = max(target_w / img.width, target_h / img.height) new_width = int(img.width * scale_factor) new_height = int(img.height * scale_factor) img_resized = img.resize((new_width, new_height), Image.Resampling.LANCZOS) crop_left = max(0, (new_width - target_w) // 2) crop_top = max(0, (new_height - target_h) // 2) crop_right = min(new_width, crop_left + target_w) crop_bottom = min(new_height, crop_top + target_h) img_cropped = img_resized.crop((crop_left, crop_top, crop_right, crop_bottom)) if img_cropped.size != (target_w, target_h): img_cropped = img_cropped.resize((target_w, target_h), Image.Resampling.LANCZOS) # ================================================== img_cropped.save(output_path, format='ICO', sizes=[(target_w, target_h)]) return True, f"生成成功:{os.path.basename(output_path)}" except Exception as e: return False, f"生成失败 {os.path.basename(output_path)}:{str(e)}" # ====================== GUI界面逻辑 ====================== class ImageConverterGUI: def __init__(self, root): self.root = root self.root.title("图片转化小工具(CSDN程序蓄)") self.root.geometry("800x600") self.root.resizable(False, False) # 初始化变量 self.input_path = tk.StringVar() self.output_dir = tk.StringVar() self.target_format = tk.StringVar(value="PNG") # 强制单个文件模式,禁用批量转换 self.is_folder = tk.BooleanVar(value=False) # ICO尺寸选择变量(常用尺寸复选框) self.ico_size_vars = { (16, 16): tk.BooleanVar(value=True), (32, 32): tk.BooleanVar(value=True), (48, 48): tk.BooleanVar(value=True), (64, 64): tk.BooleanVar(value=False), (128, 128): tk.BooleanVar(value=False), (256, 256): tk.BooleanVar(value=False) } self.custom_ico_sizes = tk.StringVar(value="") self._create_widgets() def _create_widgets(self): frame_input = ttk.LabelFrame(self.root, text="输入选择") frame_input.pack(padx=10, pady=8, fill=tk.X) ttk.Radiobutton(frame_input, text="单个文件", variable=self.is_folder, value=False, state="disabled").grid(row=0, column=0, padx=5, pady=5) self.entry_input = ttk.Entry(frame_input, textvariable=self.input_path, state="readonly") self.entry_input.grid(row=1, column=0, columnspan=2, padx=5, pady=5, sticky=tk.EW) self.btn_select_input = ttk.Button(frame_input, text="选择文件", command=self._select_input) self.btn_select_input.grid(row=1, column=2, padx=5, pady=5) frame_output = ttk.LabelFrame(self.root, text="输出设置") frame_output.pack(padx=10, pady=8, fill=tk.X) ttk.Label(frame_output, text="输出文件夹:").grid(row=0, column=0, padx=5, pady=5, sticky=tk.W) ttk.Entry(frame_output, textvariable=self.output_dir, state="readonly").grid(row=0, column=1, padx=5, pady=5, sticky=tk.EW) ttk.Button(frame_output, text="选择", command=self._select_output_dir).grid(row=0, column=2, padx=5, pady=5) ttk.Label(frame_output, text="目标格式:").grid(row=1, column=0, padx=5, pady=5, sticky=tk.W) format_options = ["PNG", "JPEG", "BMP", "ICO", "GIF"] ttk.Combobox(frame_output, textvariable=self.target_format, values=format_options, state="readonly").grid( row=1, column=1, padx=5, pady=5, sticky=tk.EW) self.frame_ico = ttk.LabelFrame(frame_output, text="ICO尺寸选择(仅支持正方形,最大256x256)") self.frame_ico.columnconfigure(1, weight=1) common_sizes_frame = ttk.Frame(self.frame_ico) common_sizes_frame.grid(row=0, column=0, columnspan=3, padx=5, pady=5, sticky=tk.W) size_options = [(16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)] for i, size in enumerate(size_options): ttk.Checkbutton( common_sizes_frame, text=f"{size[0]}x{size[1]}", variable=self.ico_size_vars[size] ).grid(row=0, column=i, padx=8, pady=3) ttk.Label(self.frame_ico, text="自定义尺寸(分号分隔,如:32,32;64,64):").grid( row=1, column=0, padx=5, pady=5, sticky=tk.W) ttk.Entry(self.frame_ico, textvariable=self.custom_ico_sizes).grid( row=1, column=1, padx=5, pady=5, sticky=tk.EW) ttk.Label(self.frame_ico, text="示例:16,16;32,32;48,48", font=("Arial", 8)).grid( row=1, column=2, padx=5, pady=5) btn_convert = ttk.Button(self.root, text="开始转换", command=self._start_convert) btn_convert.pack(padx=10, pady=10, ipady=5) frame_log = ttk.LabelFrame(self.root, text="转换日志") frame_log.pack(padx=10, pady=8, fill=tk.BOTH, expand=True) scrollbar = ttk.Scrollbar(frame_log) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.text_log = tk.Text(frame_log, yscrollcommand=scrollbar.set, wrap=tk.WORD, state="disabled", font=("Consolas", 9)) self.text_log.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) scrollbar.config(command=self.text_log.yview) self.target_format.trace_add("write", self._toggle_ico_settings) self._toggle_ico_settings() def _toggle_input_type(self): pass def _toggle_ico_settings(self, *args): if self.target_format.get() == "ICO": self.frame_ico.grid(row=2, column=0, columnspan=3, padx=5, pady=5, sticky=tk.EW) else: self.frame_ico.grid_forget() def _select_input(self): path = filedialog.askopenfilename( title="选择待转换的图片", filetypes=[("图片文件", "*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.tiff"), ("所有文件", "*.*")] ) if path: self.input_path.set(path) self._log(f"✅ 已选择输入文件:{path}") def _select_output_dir(self): path = filedialog.askdirectory(title="选择输出文件夹") if path: self.output_dir.set(path) self._log(f"✅ 已选择输出文件夹:{path}") def _log(self, msg): from datetime import datetime timestamp = datetime.now().strftime("[%H:%M:%S]") self.text_log.config(state="normal") self.text_log.insert(tk.END, f"{timestamp} {msg}\n") self.text_log.see(tk.END) # 自动滚动到最后一行 self.text_log.config(state="disabled") def _parse_ico_sizes(self): """解析勾选的ICO尺寸 + 自定义尺寸""" # 1. 获取勾选的常用尺寸 selected_sizes = [size for size, var in self.ico_size_vars.items() if var.get()] self._log(f"📌 勾选的常用尺寸:{[f'{w}x{h}' for w, h in selected_sizes]}") try: custom_sizes_str = self.custom_ico_sizes.get().strip() self._log(f"📌 自定义尺寸输入:{custom_sizes_str if custom_sizes_str else '无'}") if custom_sizes_str: custom_sizes = [] for part in custom_sizes_str.split(";"): part = part.strip() if part: w, h = part.split(",") custom_size = (int(w.strip()), int(h.strip())) custom_sizes.append(custom_size) for custom_size in custom_sizes: if custom_size not in selected_sizes: selected_sizes.append(custom_size) self._log(f"➕ 添加自定义尺寸:{custom_size[0]}x{custom_size[1]}") except Exception as e: self._log(f"⚠️ 自定义尺寸解析失败:{str(e)}") messagebox.warning("警告", f"自定义尺寸格式错误:{str(e)}\n将仅使用勾选的尺寸") if not selected_sizes: selected_sizes = [(16, 16), (32, 32), (48, 48)] self._log("⚠️ 未选择任何ICO尺寸,使用默认尺寸:16x16, 32x32, 48x48") self._log(f"📋 最终待生成的尺寸列表:{[f'{w}x{h}' for w, h in selected_sizes]}") return selected_sizes def _start_convert(self): input_path = self.input_path.get().strip() output_dir = self.output_dir.get().strip() target_format = self.target_format.get() if not input_path: messagebox.showerror("错误", "请先选择输入文件!") return if not output_dir: messagebox.showerror("错误", "请先选择输出文件夹!") return self._log("=" * 70) self._log(f"🚀 开始转换,目标格式:{target_format}") # 执行单个文件转换 self._single_convert(input_path, output_dir, target_format) self._log("✅ 转换任务完成!") messagebox.showinfo("完成", "转换任务已执行完毕,请查看日志确认结果!") def _single_convert(self, input_file, output_dir, target_format): filename = os.path.basename(input_file) name_without_ext = os.path.splitext(filename)[0] if target_format == "ICO": ico_sizes = self._parse_ico_sizes() for size in ico_sizes: w, h = size output_path = os.path.join(output_dir, f"{name_without_ext}_{w}x{h}.ico") success, msg = create_single_size_ico(input_file, output_path, size) self._log(msg) else: # 普通格式转换 output_ext = f".{target_format.lower()}" output_path = os.path.join(output_dir, f"{name_without_ext}{output_ext}") success, msg = convert_image(input_file, output_path, target_format) self._log(msg) # ====================== 程序入口 ====================== if __name__ == "__main__": # 启动GUI root = tk.Tk() app = ImageConverterGUI(root) root.mainloop()
核心思路
📥 前期准备
- 环境配置 :确保电脑安装了 Python,打开命令行输入
pip install --upgrade pillow安装 / 升级图片处理依赖库(这是工具能正常运行的基础); - 启动工具:双击运行工具的 Python 脚本,弹出操作窗口即可开始使用。
🚀 核心操作步骤(5 步完成转换)
- 选待转换图片:在窗口「输入选择」区域点击「选择文件」,从电脑中挑选要转换的图片(支持 PNG、JPG、BMP、GIF、TIFF 等常见格式),选好后日志区会显示已选文件路径;
- 指定保存位置:在「输出设置」区域点击「选择」按钮,选一个文件夹作为 ICO 文件的保存路径,日志区会同步显示保存位置;
- 选目标格式为 ICO:点击「目标格式」下拉菜单,选择「ICO」选项,窗口会自动展开「ICO 尺寸选择」区域;
- 选需要的 ICO 尺寸 :
- 常用尺寸:直接勾选 16x16、32x32、48x48 等预设尺寸(可多选);
- 自定义尺寸:在输入框按「宽,高;宽,高」格式填写(如 50,50;64,64),多个尺寸用分号分隔,工具会自动解析并去重;
- 若未选任何尺寸,工具会默认使用 16x16、32x32、48x48 三个常用尺寸;
- 开始转换:点击「开始转换」按钮,工具会自动处理图片并生成 ICO 文件,日志区会实时显示每个尺寸的生成状态(成功 / 失败),转换完成后会弹出 "转换任务完成" 提示。
💡 关键特性与注意事项
- 智能处理非标准图片:若原图是长方形、扁形等非正方形,工具会先按比例缩放至覆盖目标尺寸,再从图片中心裁剪出正方形区域(类似裁证件照),避免 ICO 变形;
- 兼容 Windows 系统:生成的 ICO 文件用 PIL 库原生功能保存,百分百兼容 Windows,可直接用照片查看器打开,每个尺寸对应一个独立文件(命名规则:原文件名_宽 x 高.ico);
- 容错与提示 :
- 若自定义尺寸格式错误(如输成 32,32),日志区会提示错误,仍会用勾选的尺寸继续转换;
- 转换 JPG 图片时,会自动用白色填充透明区域(JPG 不支持透明);
- 日志区带时间戳,可清晰查看每一步操作结果,方便排查问题;
- 中文适配:工具界面已适配 Windows 中文显示,不会出现乱码问题。
📂 查看结果
转换完成后,前往选定的保存文件夹,即可看到生成的 ICO 文件(如图标_16x16.ico、图标_32x32.ico),直接双击就能正常打开,非正方形原图转换后的 ICO 会保持内容居中、无变形。