Python 2.7如何实现.ico图标颜色反转适配Windows系统主题托盘显示
Python2.7 实现Windows托盘ICO图标按主题颜色反转方案
核心逻辑为将ICO文件加载为可编辑的像素矩阵,完成颜色反转后转换为可用的HICON句柄,兼容你现有win32API调用逻辑。
前置依赖安装
- 安装适配Python2.7的图像处理库:
pip install pillow==4.2.1(Pillow 4.2.1是最后一个支持Python2.7的官方版本) - 确保已安装适配Python2.7的pywin32库
核心实现代码
import os import win32gui import win32con import win32api import win32ui from PIL import Image import _winreg as winreg # Python2.7 注册表模块名称为 _winreg def is_light_theme(): # Win10及以上系统读取注册表判断主题,低版本系统默认返回亮色主题 try: reg_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize") value, _ = winreg.QueryValueEx(reg_key, "SystemUsesLightTheme") winreg.CloseKey(reg_key) return value == 1 except: return True def get_hicon(self, icon): hicon = None hinst = win32gui.GetModuleHandle(None) if not icon or not os.path.isfile(icon): return hicon # 判断是否需要反转:暗色主题下反转图标,亮色主题走原有逻辑 need_invert = not is_light_theme() if not need_invert: icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON) ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON) hicon = win32gui.LoadImage(hinst, icon, win32con.IMAGE_ICON, ico_x, ico_y, icon_flags) return hicon # 反转图标逻辑 ico_size = win32api.GetSystemMetrics(win32con.SM_CXSMICON) # 加载ICO为RGBA格式的PIL图像 img = Image.open(icon).convert("RGBA").resize((ico_size, ico_size)) pixels = img.load() # 遍历像素反转RGB通道,保留Alpha透明通道 for x in range(img.width): for y in range(img.height): r, g, b, a = pixels[x, y] pixels[x, y] = (255 - r, 255 - g, 255 - b, a) # 将PIL图像转换为HICON句柄 screen_dc = win32gui.GetDC(0) hdc = win32ui.CreateDCFromHandle(screen_dc) hbmp = win32ui.CreateBitmap() hbmp.CreateCompatibleBitmap(hdc, img.width, img.height) mem_dc = hdc.CreateCompatibleDC() mem_dc.SelectObject(hbmp) # 写入反转后的像素 for x in range(img.width): for y in range(img.height): r, g, b, a = pixels[x, y] mem_dc.SetPixel(x, y, win32api.RGB(r, g, b)) # 生成图标句柄 hicon = win32gui.CreateIconFromResourceEx( hbmp.GetBitmapBits(True), True, # 标记为图标资源 0x00030000, # 图标资源版本号 img.width, img.height, win32con.LR_DEFAULTCOLOR ) # 释放资源避免内存泄漏 win32gui.DeleteObject(hbmp.GetHandle()) mem_dc.DeleteDC() hdc.DeleteDC() win32gui.ReleaseDC(0, screen_dc) return hicon
注意事项
- 不需要自动适配系统主题的话,直接删除
need_invert相关判断,每次都走反转分支即可 - 代码保留了原图的Alpha透明通道,不会出现半透明图标反转后透明区域失效的问题
- 原有调用
get_hicon的逻辑不需要做任何修改,替换方法实现即可生效
内容的提问来源于stack exchange,提问作者Rushikesh Korde
相关产品推荐
相关产品推荐

