【DeepSeek创作】IMG2ICO,图片转ICO工具 源码
本帖最后由 key0527 于 2025-7-23 18:56 编辑大概花了2小时沟通
DeepSeek 问小白 沟通过程:
https://www.wenxiaobai.com/share/chat/2a426d54-d18d-4821-92b4-d32ef1dc2ecd
所需依赖库:
pip install pillow pyinstaller ttkbootstrap
源码+图标+成品+打包bat 全在(后续什么工具都在这):
网盘链接: https://pan.baidu.com/s/5MCmy-a7m0B2N9b_z-28aHA?
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from PIL import Image
import os
import sys
import subprocess
class ICOConverterApp:
def __init__(self, root):
# 初始化主窗口
self.root = root
self.root.title("图片转ICO图标工具")
self.root.geometry("540x450")# 设置窗口大小为540x450
self.root.resizable(False, False)
# 尝试设置程序图标
try:
# 尝试从打包资源加载图标
self.root.iconbitmap(self.resource_path("img2ico.ico"))
except Exception:
try:
# 尝试从当前目录加载
if os.path.exists("img2ico.ico"):
self.root.iconbitmap("img2ico.ico")
except:
pass
# 创建主框架
main_frame = ttk.Frame(root, padding=10)
main_frame.pack(fill=tk.BOTH, expand=True)
# 输入图片部分
input_frame = ttk.LabelFrame(main_frame, text="输入设置", padding=(10, 5))
input_frame.pack(fill=tk.X, pady=5)
ttk.Label(input_frame, text="输入图片路径:").grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)
self.input_path = tk.StringVar()
input_entry = ttk.Entry(input_frame, textvariable=self.input_path, width=40)
input_entry.grid(row=0, column=1, padx=5, pady=5)
input_btn = ttk.Button(input_frame, text="浏览...", command=self.browse_input)
input_btn.grid(row=0, column=2, padx=5, pady=5)
# 输出设置部分
output_frame = ttk.LabelFrame(main_frame, text="输出设置", padding=(10, 5))
output_frame.pack(fill=tk.X, pady=5)
ttk.Label(output_frame, text="输出ICO路径:").grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)
self.output_path = tk.StringVar()
output_entry = ttk.Entry(output_frame, textvariable=self.output_path, width=40)
output_entry.grid(row=0, column=1, padx=5, pady=5)
output_btn = ttk.Button(output_frame, text="浏览...", command=self.browse_output)
output_btn.grid(row=0, column=2, padx=5, pady=5)
# 尺寸选择部分(高度减少)
size_frame = ttk.LabelFrame(main_frame, text="选择尺寸 (可多选)", padding=10)
size_frame.pack(fill=tk.BOTH, expand=True, pady=5)
# 创建滚动区域容器(固定高度为150像素)
scroll_container = ttk.Frame(size_frame)
scroll_container.pack(fill=tk.BOTH, expand=True)
# 创建滚动区域
canvas = tk.Canvas(scroll_container, height=150)# 限制高度为150px
scrollbar = ttk.Scrollbar(scroll_container, orient="vertical", command=canvas.yview)
scrollable_frame = ttk.Frame(canvas)
# 配置滚动区域
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
)
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
# 放置滚动区域
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
# 尺寸选择变量
self.size_vars = {}
# 所有可用尺寸
all_sizes =
# 默认选中的尺寸
default_sizes =
# 创建尺寸选择复选框 (每行5个以节省空间)
for i, size in enumerate(all_sizes):
self.size_vars = tk.BooleanVar(value=(size in default_sizes))
chk = ttk.Checkbutton(scrollable_frame, text=f"{size}x{size}",
variable=self.size_vars)
# 每行5个
chk.grid(row=i//5, column=i%5, sticky=tk.W, padx=8, pady=3)# 减少边距
# 按钮区域 - 放在尺寸框架外面
btn_frame = ttk.Frame(main_frame)
btn_frame.pack(fill=tk.X, pady=10)
# 左侧按钮组
left_btn_frame = ttk.Frame(btn_frame)
left_btn_frame.pack(side=tk.LEFT, fill=tk.X)
select_all_btn = ttk.Button(left_btn_frame, text="全选", command=self.select_all_sizes, width=8)
select_all_btn.pack(side=tk.LEFT, padx=5)
select_none_btn = ttk.Button(left_btn_frame, text="清空", command=self.select_no_sizes, width=8)
select_none_btn.pack(side=tk.LEFT, padx=5)
# 中间按钮组
center_btn_frame = ttk.Frame(btn_frame)
center_btn_frame.pack(side=tk.LEFT, fill=tk.X, expand=True)
# 右侧按钮组
right_btn_frame = ttk.Frame(btn_frame)
right_btn_frame.pack(side=tk.RIGHT, fill=tk.X)
# 主要操作按钮放在中间
convert_btn = ttk.Button(center_btn_frame, text="开始转换", command=self.convert_image, width=15)
convert_btn.pack(side=tk.LEFT, padx=10)
exit_btn = ttk.Button(right_btn_frame, text="退出程序", command=self.exit_app, width=10)
exit_btn.pack(side=tk.RIGHT, padx=10)
# 状态栏
self.status_var = tk.StringVar(value="就绪")
status_bar = ttk.Label(root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
status_bar.pack(side=tk.BOTTOM, fill=tk.X)
# 设置初始值
self.output_path.set(os.path.join(os.getcwd(), "output.ico"))
def resource_path(self, relative_path):
""" 获取资源的绝对路径,用于打包后的程序 """
try:
# PyInstaller创建的临时文件夹路径
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
def select_all_sizes(self):
"""全选所有尺寸"""
for var in self.size_vars.values():
var.set(True)
def select_no_sizes(self):
"""清除所有尺寸选择"""
for var in self.size_vars.values():
var.set(False)
def browse_input(self):
"""浏览并选择输入图片文件"""
filetypes = (
("图片文件", "*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.webp"),
("所有文件", "*.*")
)
filepath = filedialog.askopenfilename(
title="选择图片文件",
initialdir=os.getcwd(),
filetypes=filetypes
)
if filepath:
self.input_path.set(filepath)
# 自动设置输出文件名 - 在源文件同目录下
output_dir = os.path.dirname(filepath)
filename = os.path.splitext(os.path.basename(filepath)) + ".ico"
self.output_path.set(os.path.join(output_dir, filename))
def browse_output(self):
"""浏览并选择输出ICO文件路径"""
filetypes = (
("ICO文件", "*.ico"),
("所有文件", "*.*")
)
filepath = filedialog.asksaveasfilename(
title="保存ICO文件",
initialdir=os.path.dirname(self.output_path.get()),
initialfile=os.path.basename(self.output_path.get()),
defaultextension=".ico",
filetypes=filetypes
)
if filepath:
self.output_path.set(filepath)
def convert_image(self):
"""执行图片转换操作"""
input_path = self.input_path.get()
output_path = self.output_path.get()
# 验证输入
if not input_path:
messagebox.showerror("错误", "请选择输入图片路径")
return
if not output_path:
messagebox.showerror("错误", "请设置输出ICO路径")
return
# 获取选中的尺寸
selected_sizes =
if not selected_sizes:
messagebox.showerror("错误", "请至少选择一个尺寸")
return
# 检查输入文件是否存在
if not os.path.isfile(input_path):
messagebox.showerror("错误", f"输入文件不存在: {input_path}")
return
# 检查输出目录是否存在
output_dir = os.path.dirname(output_path)
if not os.path.isdir(output_dir):
try:
os.makedirs(output_dir)
except Exception as e:
messagebox.showerror("错误", f"无法创建输出目录: {str(e)}")
return
# 更新状态
self.status_var.set("转换中...")
self.root.update()
try:
# 打开原始图片
img = Image.open(input_path)
# 确保图片是RGBA模式(支持透明通道)
if img.mode != 'RGBA':
img = img.convert('RGBA')
# 创建不同尺寸的图片列表
icon_images = []
for size in selected_sizes:
# 创建正方形画布(透明背景)
canvas = Image.new('RGBA', (size, size), (0, 0, 0, 0))
# 计算缩放比例并调整图片大小
ratio = min(size / img.width, size / img.height)
new_width = int(img.width * ratio)
new_height = int(img.height * ratio)
resized_img = img.resize((new_width, new_height), Image.LANCZOS)
# 将缩放后的图片居中放在画布上
position = (
(size - new_width) // 2,
(size - new_height) // 2
)
canvas.paste(resized_img, position, resized_img)
icon_images.append(canvas)
# 按尺寸从小到大排序 (ICO文件需要)
icon_images.sort(key=lambda img: img.width)
selected_sizes_sorted = sorted(selected_sizes)
# 保存为ICO格式(包含所有尺寸)
icon_images.save(
output_path,
format='ICO',
append_images=icon_images,
sizes=[(s, s) for s in selected_sizes_sorted]
)
# 转换成功
self.status_var.set(f"转换成功! 已保存到: {output_path}")
# 询问用户是否打开输出目录
response = messagebox.askyesno("成功",
f"图片已成功转换为ICO图标!\n\n"
f"保存位置: {output_path}\n"
f"包含尺寸: {', '.join(map(str, selected_sizes_sorted))}\n\n"
"是否打开输出目录?")
if response:
# 打开输出目录
output_dir = os.path.dirname(output_path)
if os.path.exists(output_dir):
# 跨平台打开目录
if sys.platform == "win32":
os.startfile(output_dir)
elif sys.platform == "darwin":
subprocess.Popen(["open", output_dir])
else:
subprocess.Popen(["xdg-open", output_dir])
except Exception as e:
# 转换失败
self.status_var.set(f"转换失败: {str(e)}")
messagebox.showerror("错误", f"转换失败: {str(e)}")
def exit_app(self):
"""退出程序"""
self.root.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = ICOConverterApp(root)
root.mainloop() 【公告】禁止纯AI生成代码使用原创标签
https://www.52pojie.cn/thread-2046647-1-1.html
(出处: 吾爱破解论坛)
可以的,至少是能完成目标的,就怕有py+AI还搞不定简单的小工具就真要好好学习了。{:1_918:} ,源码+图标+成品+打包bat 这样分享东西真的很不错,都给完了。并且还给了AI提问过程,新来的萌新就很容易跟着做了。论坛就需要你们
300行代码需要2小时沟通的话 说明你的需求不明确 新手,来学习的, 感谢大佬,学习了 璐璐诺 发表于 2025-7-23 13:20
300行代码需要2小时沟通的话 说明你的需求不明确
我可能需要半天时间 小白学代码有入门吗 感觉有用,帮楼主顶一下 还是非常感谢地
感谢大佬,这个还是可以学习一下,虽然也没看懂。。。