在开发工具或者小软件的时候,我们常常会遇到一个问题,如果把我的png/jpg等一些图片,快速生成一个专业的.ico图标,用于程序或者快捷方式上呢?
市面上虽然有很多网站可以转换,不过繁琐,有广告,甚至还有限制收费,主要还要上传至他人服务器处理,安全性上也有顾虑。
今天,我们就借助Python+Tkinter+tkinterdnd2写了一个拖拽图片生成Icon小工具:
拖拽即可生成.ico,支持多尺寸(16~256),支持多图片格式(PNG / JPG / BMP / WEBP),启动快、不占资源,不需要任何额外软件,可以快速上手!

需要的源码和程序exe的,可以 关注+留言666,我会私信发你。也可自行编译
需要两个库:一个是pillow,用于图片处理,另一个是tkinterdnd2。
由于Tkinter原生不支持拖拽文件,所以我们需要借助轻量扩展库tkinterdnd2来帮我们实现,来执行命令,安装下必要的库
pip install pillow tkinterdnd2#图片等比缩放并居中def resize_keep_ratio(img, size): img = img.copy() img.thumbnail((size, size), Image.LANCZOS) canvas = Image.new("RGBA", (size, size), (0, 0, 0, 0)) x = (size - img.width) // 2 y = (size - img.height) // 2 canvas.paste(img, (x, y)) return canvas#单张图片转icodef convert_image_to_ico(image_path, size): """生成单尺寸 ico""" if not image_path.lower().endswith(SUPPORTED_EXT): return False, "不支持的图片格式" try: img = Image.open(image_path) if img.mode != "RGBA": img = img.convert("RGBA") icon_img = resize_keep_ratio(img, size) base, _ = os.path.splitext(image_path) ico_path = f"{base}_{size}.ico" icon_img.save( ico_path, format="ICO", sizes=[(size, size)] ) return True, ico_path except Exception as e: return False, str(e) #拖拽区域 self.drop_area = tk.Label( self, text="拖拽图片到这里\n自动生成 .ico", font=("Segoe UI", 14), bg="#ffffff", fg="#333333", width=34, height=7, relief="ridge" ) self.drop_area.pack(pady=20) #拖拽事件绑定 self.drop_area.drop_target_register(DND_FILES) self.drop_area.dnd_bind("<<Drop>>", self.on_drop) #拖拽处理 def on_drop(self, event): files = self.tk.splitlist(event.data) size = self.size_var.get() self.status.config(text=f"正在生成 {size}x{size} icon…") threading.Thread( target=self.process_files, args=(files, size), daemon=True ).start()我们将处理工作放于后台线程,这样主界面不卡顿。
完整代码
import osimport threadingimport tkinter as tkfrom tkinter import ttk,messageboxfrom PIL import Imagefrom tkinterdnd2 import TkinterDnD, DND_FILES#支持的图标尺寸ICON_SIZE_OPTIONS = [16, 24, 32, 48, 64, 128, 256]#支持的图片格式SUPPORTED_EXT = (".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".webp")#图片等比缩放并居中def resize_keep_ratio(img, size): img = img.copy() img.thumbnail((size, size), Image.LANCZOS) canvas = Image.new("RGBA", (size, size), (0, 0, 0, 0)) x = (size - img.width) // 2 y = (size - img.height) // 2 canvas.paste(img, (x, y)) return canvas#单张图片转icodef convert_image_to_ico(image_path, size): """生成单尺寸 ico""" if not image_path.lower().endswith(SUPPORTED_EXT): return False, "不支持的图片格式" try: img = Image.open(image_path) if img.mode != "RGBA": img = img.convert("RGBA") icon_img = resize_keep_ratio(img, size) base, _ = os.path.splitext(image_path) ico_path = f"{base}_{size}.ico" icon_img.save( ico_path, format="ICO", sizes=[(size, size)] ) return True, ico_path except Exception as e: return False, str(e)#界面class Img2IcoApp(TkinterDnD.Tk): def __init__(self): super().__init__() self.title("图片 → Icon 转换工具 By 小海代码人生") self.geometry("460x320") self.resizable(False, False) self.configure(bg="#f2f2f2") #拖拽区域 self.drop_area = tk.Label( self, text="拖拽图片到这里\n自动生成 .ico", font=("Segoe UI", 14), bg="#ffffff", fg="#333333", width=34, height=7, relief="ridge" ) self.drop_area.pack(pady=20) #尺寸选择 size_frame = tk.Frame(self, bg="#f2f2f2") size_frame.pack(pady=5) tk.Label( size_frame, text="Icon 尺寸:", font=("Segoe UI", 11), bg="#f2f2f2" ).pack(side=tk.LEFT) self.size_var = tk.IntVar(value=256) self.size_combo = ttk.Combobox( size_frame, textvariable=self.size_var, values=ICON_SIZE_OPTIONS, width=8, state="readonly" ) self.size_combo.pack(side=tk.LEFT, padx=5) tk.Label( size_frame, text="x", font=("Segoe UI", 11), bg="#f2f2f2" ).pack(side=tk.LEFT) tk.Label( size_frame, textvariable=self.size_var, font=("Segoe UI", 11), bg="#f2f2f2" ).pack(side=tk.LEFT) #处理状态 self.status = tk.Label( self, text="选择尺寸后,拖拽图片即可生成", font=("Segoe UI", 10), bg="#f2f2f2", fg="#666666" ) self.status.pack(pady=10) #拖拽绑定 self.drop_area.drop_target_register(DND_FILES) self.drop_area.dnd_bind("<<Drop>>", self.on_drop) #拖拽处理 def on_drop(self, event): files = self.tk.splitlist(event.data) size = self.size_var.get() self.status.config(text=f"正在生成 {size}x{size} icon…") threading.Thread( target=self.process_files, args=(files, size), daemon=True ).start() def process_files(self, files, size): success = 0 errors = [] for path in files: ok, msg = convert_image_to_ico(path, size) if ok: success += 1 else: errors.append(f"{os.path.basename(path)}:{msg}") self.after(0, self.finish, success, errors, size) def finish(self, success, errors, size): if errors: messagebox.showerror("部分失败", "\n".join(errors)) if success: self.status.config( text=f"✔ 已生成 {success} 个 {size}x{size} icon" ) else: self.status.config(text="未生成 icon")if __name__ == "__main__": app = Img2IcoApp() app.iconbitmap("app.ico") #设置窗口图标 app.mainloop()这款 Python 小工具轻巧便携、即开即用,拖拽图片即可生成 Icon,支持多尺寸选择;无需复杂操作,几秒就能完成图标生成,支持多张、批量处理。
