You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python从exe文件中提取ico/png格式图标文件

从EXE文件提取图标适配Tkinter程序启动器的实现方案

你可以根据自己的需求选下面两种方案,都能拿到可直接给Tkinter按钮用的图标,也支持导出为.ico/.png格式本地文件。


方案1:调用Windows系统原生API(无重型依赖,兼容性最好,推荐)

Windows自带的SHGetFileInfo接口可以直接读取任意exe(包括加壳程序)的图标,和资源管理器显示的图标完全一致,不需要手动解析PE文件结构。

  • 依赖:只需要装Pillow做图片格式转换,Tkinter是Python标准库自带
    pip install pillow
  • 可直接复用的代码:
import ctypes
from ctypes import wintypes
import tkinter as tk
from PIL import Image, ImageTk

# 系统API常量定义
SHGFI_ICON = 0x100
SHGFI_LARGEICON = 0x0  # 默认32*32大图标
SHGFI_SMALLICON = 0x1  # 16*16小图标

class SHFILEINFO(ctypes.Structure):
    _fields_ = [
        ("hIcon", wintypes.HICON),
        ("iIcon", ctypes.c_int),
        ("dwAttributes", wintypes.DWORD),
        ("szDisplayName", wintypes.WCHAR * 260),
        ("szTypeName", wintypes.WCHAR * 80),
    ]

def get_exe_icon_for_tk(exe_path: str, icon_size: tuple[int, int] = (36, 36)) -> ImageTk.PhotoImage:
    """
    输入exe路径,返回可直接赋值给Tkinter组件image属性的图标对象
    不需要落地保存图标文件,直接在内存中完成转换
    """
    shfi = SHFILEINFO()
    # 获取图标句柄
    ctypes.windll.shell32.SHGetFileInfoW(
        exe_path, 0, ctypes.byref(shfi), ctypes.sizeof(shfi),
        SHGFI_ICON | SHGFI_LARGEICON
    )
    # 把图标句柄转为PIL Image对象
    hdc = ctypes.windll.user32.GetDC(0)
    hbmp = ctypes.windll.gdi32.CreateCompatibleBitmap(hdc, icon_size[0], icon_size[1])
    mem_dc = ctypes.windll.gdi32.CreateCompatibleDC(hdc)
    old_obj = ctypes.windll.gdi32.SelectObject(mem_dc, hbmp)
    
    ctypes.windll.user32.DrawIconEx(mem_dc, 0, 0, shfi.hIcon, icon_size[0], icon_size[1], 0, 0, 0x0003)
    bmpinfo = ctypes.create_string_buffer(40)
    ctypes.memmove(bmpinfo, ctypes.byref(ctypes.c_int(40)), 4)
    ctypes.memmove(ctypes.c_void_p(ctypes.addressof(bmpinfo)+4), ctypes.byref(ctypes.c_int(icon_size[0])), 4)
    ctypes.memmove(ctypes.c_void_p(ctypes.addressof(bmpinfo)+8), ctypes.byref(ctypes.c_int(icon_size[1])), 4)
    ctypes.memmove(ctypes.c_void_p(ctypes.addressof(bmpinfo)+12), ctypes.byref(ctypes.c_short(1)), 2)
    ctypes.memmove(ctypes.c_void_p(ctypes.addressof(bmpinfo)+14), ctypes.byref(ctypes.c_short(32)), 2)
    
    pixel_buffer = ctypes.create_string_buffer(icon_size[0] * icon_size[1] * 4)
    ctypes.windll.gdi32.GetDIBits(mem_dc, hbmp, 0, icon_size[1], pixel_buffer, bmpinfo, 0)
    
    # 释放系统资源
    ctypes.windll.gdi32.SelectObject(mem_dc, old_obj)
    ctypes.windll.gdi32.DeleteDC(mem_dc)
    ctypes.windll.gdi32.DeleteObject(hbmp)
    ctypes.windll.user32.ReleaseDC(0, hdc)
    ctypes.windll.user32.DestroyIcon(shfi.hIcon)
    
    # 转为Tkinter可用的PhotoImage
    img = Image.frombuffer("RGBA", icon_size, pixel_buffer, "raw", "BGRA", 0, 1)
    return ImageTk.PhotoImage(img)

# 调用示例:给按钮绑定图标
if __name__ == "__main__":
    root = tk.Tk()
    notepad_icon = get_exe_icon_for_tk("C:/Windows/notepad.exe")
    # 注意:一定要把图片对象绑定到组件属性上,否则会被GC回收导致图标不显示
    test_btn = tk.Button(root, text="记事本", image=notepad_icon, compound="left")
    test_btn.image = notepad_icon
    test_btn.pack(padx=20, pady=20)
    root.mainloop()

方案2:使用icoextract库导出本地图标文件(适合需要缓存图标场景)

如果你需要把提取到的图标存成本地.ico/.png文件做缓存,避免每次启动程序都重新提取,可以用专门的icoextract库,它会自动解析exe的PE资源段提取图标。

  • 安装依赖:
    pip install icoextract pillow
  • 提取并保存图标的代码:
from icoextract import IconExtractor
from PIL import Image
import os

def export_exe_icon(exe_path: str, save_path: str, target_size: tuple[int,int] = (48,48), fmt: str = "png"):
    """
    从exe提取主图标,保存为指定格式的本地文件
    fmt支持ico/png/jpg等Pillow兼容的图片格式
    """
    extractor = IconExtractor(exe_path)
    # 读取主图标的字节流
    icon_stream = extractor.get_icon(num=0)
    # 转成PIL对象调整尺寸
    img = Image.open(icon_stream)
    img = img.resize(target_size, Image.Resampling.LANCZOS)
    img.save(save_path, format=fmt)

# 调用示例
export_exe_icon("C:/Windows/notepad.exe", "./notepad_icon.png", target_size=(48,48), fmt="png")

注意事项

  • 部分加壳、加密的exe无法通过解析PE结构的方式提取图标,这种场景优先用方案1,只要资源管理器能正常显示的图标,方案1都能拿到
  • Tkinter的PhotoImage对象会被Python垃圾回收机制回收,绑定到按钮后一定要把图片对象赋值给按钮的image属性或者全局变量,否则按钮会显示空白
  • 如果不需要缓存图标,优先用方案1,全程内存操作性能更好,不会产生临时文件

内容的提问来源于stack exchange,提问作者Manhunter1920

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:45:33