使用Python从.exe文件中提取图标

在这篇博客中,我们将学习如何使用Python和一些Windows特定的库来从.exe文件中提取图标,并将其保存为.png文件。

依赖库

我们的代码需要以下Python库:

  • win32ui
  • win32gui
  • PIL

如果你还没有安装这些库,可以使用pip进行安装:

pip install pywin32 pillow

环境准备

确保你已经安装了Python,并且可以使用pip安装所需的库。

详细步骤

  1. 安装依赖库:确保你已经安装了pywin32pillow库。
  2. 定义函数:创建一个名为get_exe_icon的函数,用于从.exe文件中提取图标。
  3. 提取图标:使用win32gui.ExtractIconEx函数从.exe文件中提取图标。
  4. 创建设备上下文:使用win32ui.CreateDCFromHandlewin32ui.CreateBitmap创建一个设备上下文,并在其中绘制图标。
  5. 绘制图标:在设备上下文中绘制提取的图标。
  6. 保存图标:将绘制的图标保存为.png文件。

提取图标

我们首先需要一个函数来从.exe文件中提取图标。我们可以使用win32gui和win32ui库来完成这个任务。以下是get_exe_icon函数的代码:

代码解析

  1. 导入库

    import win32ui
    import win32gui
    from PIL import Image
    

    这里我们导入了win32uiwin32gui库,用于与Windows API进行交互,以及PIL库(Python Imaging Library)用于图像处理。

  2. 定义函数

    def get_exe_icon(exe_path):
    

    定义一个名为get_exe_icon的函数,接受一个参数exe_path,表示.exe文件的路径。

  3. 提取图标

    large, small = win32gui.ExtractIconEx(exe_path, 0)
    win32gui.DestroyIcon(small[0])
    

    使用win32gui.ExtractIconEx函数从指定的.exe文件中提取图标。largesmall分别表示大图标和小图标。这里我们只使用大图标,并销毁小图标以释放资源。

  4. 创建设备上下文

    hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
    hbmp = win32ui.CreateBitmap()
    hbmp.CreateCompatibleBitmap(hdc, 32, 32)
    

    创建一个设备上下文(Device Context,简称DC),用于绘制图标。CreateDCFromHandle函数从句柄创建一个DC,CreateBitmap函数创建一个位图对象,并使用CreateCompatibleBitmap函数使其与DC兼容。

  5. 绘制图标

    hdc = hdc.CreateCompatibleDC()
    hdc.SelectObject(hbmp)
    hdc.DrawIcon((0, 0), large[0])
    

    创建一个兼容的DC,并选择位图对象到DC中。使用DrawIcon函数在DC中绘制图标。

  6. 保存图标

    bmpinfo = hbmp.GetInfo()
    bmpstr = hbmp.GetBitmapBits(True)
    img = Image.frombuffer(
        'RGB',
        (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
        bmpstr, 'raw', 'BGRX', 0, 1)
    img.save('icon.png')
    

    获取位图信息和位图的位数据。使用PIL库的Image.frombuffer函数将位图数据转换为图像对象,并将图像保存为.png文件。

使用示例

以下是如何使用get_exe_icon函数的示例:

get_exe_icon(r'D:\install\Microsoft VS Code\Code.exe')

代码解析

  • win32gui.ExtractIconEx(exe_path, 0):从指定的.exe文件中提取图标。largesmall分别表示大图标和小图标。
  • win32ui.CreateDCFromHandle(win32gui.GetDC(0)):创建一个设备上下文,用于绘制图标。
  • win32ui.CreateBitmap():创建一个位图对象,用于存储绘制的图标。
  • hdc.CreateCompatibleDC():创建一个兼容的设备上下文。
  • hdc.SelectObject(hbmp):选择位图对象到设备上下文中。
  • hdc.DrawIcon((0, 0), large[0]):在设备上下文中绘制图标。
  • hbmp.GetInfo():获取位图信息。
  • hbmp.GetBitmapBits(True):获取位图的位数据。
  • Image.frombuffer(...):使用PIL库将位图数据转换为图像对象。
  • img.save('icon.png'):将图像保存为.png文件。

使用示例

以下是如何使用get_exe_icon函数的示例:

get_exe_icon(r'D:\install\Microsoft VS Code\Code.exe')

在这个示例中,我们从D:\install\Microsoft VS Code\Code.exe文件中提取图标,并将其保存为icon.png文件。

完整代码

import win32ui
import win32gui
from PIL import Image

def get_exe_icon(exe_path):
    # 获取exe文件的图标
    large, small = win32gui.ExtractIconEx(exe_path, 0)
    win32gui.DestroyIcon(small[0])

    # 创建一个设备上下文
    hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
    hbmp = win32ui.CreateBitmap()
    hbmp.CreateCompatibleBitmap(hdc, 32, 32)

    # 在设备上下文中绘制图标
    hdc = hdc.CreateCompatibleDC()
    hdc.SelectObject(hbmp)
    hdc.DrawIcon((0, 0), large[0])

    # 保存图标到本地文件
    bmpinfo = hbmp.GetInfo()
    bmpstr = hbmp.GetBitmapBits(True)
    img = Image.frombuffer(
        'RGB',
        (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
        bmpstr, 'raw', 'BGRX', 0, 1)
    img.save('icon.png')

get_exe_icon(r'D:\install\Microsoft VS Code\Code.exe')

运行结果

运行上述代码后,你将会在当前目录下看到一个名为icon.png的文件,其中包含从.exe文件中提取的图标。

效果图:

扩展1:提取多个图标

有些.exe文件可能包含多个图标。我们可以修改get_exe_icon函数来提取所有图标,并将它们保存为不同的文件。

import win32ui
import win32gui
from PIL import Image

def get_all_exe_icons(exe_path):
    # 获取exe文件的所有图标
    large, small = win32gui.ExtractIconEx(exe_path, 0, 10)  # 提取最多10个图标

    for i, icon in enumerate(large):
        # 创建一个设备上下文
        hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
        hbmp = win32ui.CreateBitmap()
        hbmp.CreateCompatibleBitmap(hdc, 32, 32)

        # 在设备上下文中绘制图标
        hdc = hdc.CreateCompatibleDC()
        hdc.SelectObject(hbmp)
        hdc.DrawIcon((0, 0), icon)

        # 保存图标到本地文件
        bmpinfo = hbmp.GetInfo()
        bmpstr = hbmp.GetBitmapBits(True)
        img = Image.frombuffer(
            'RGB',
            (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
            bmpstr, 'raw', 'BGRX', 0, 1)
        img.save(f'icon_{i}.png')

get_all_exe_icons(r'D:\install\Microsoft VS Code\Code.exe')

扩展2:提取并保存为不同格式

除了保存为.png文件,我们还可以将图标保存为其他格式,如.ico或.bmp。

import win32ui
import win32gui
from PIL import Image

def get_exe_icon(exe_path, output_format='png'):
    # 获取exe文件的图标
    large, small = win32gui.ExtractIconEx(exe_path, 0)
    win32gui.DestroyIcon(small[0])

    # 创建一个设备上下文
    hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
    hbmp = win32ui.CreateBitmap()
    hbmp.CreateCompatibleBitmap(hdc, 32, 32)

    # 在设备上下文中绘制图标
    hdc = hdc.CreateCompatibleDC()
    hdc.SelectObject(hbmp)
    hdc.DrawIcon((0, 0), large[0])

    # 保存图标到本地文件
    bmpinfo = hbmp.GetInfo()
    bmpstr = hbmp.GetBitmapBits(True)
    img = Image.frombuffer(
        'RGB',
        (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
        bmpstr, 'raw', 'BGRX', 0, 1)
    img.save(f'icon.{output_format}')

# 示例:保存为.ico文件
get_exe_icon(r'D:\install\Microsoft VS Code\Code.exe', output_format='ico')

扩展3:处理不同尺寸的图标

有些图标可能有不同的尺寸,我们可以提取并保存这些不同尺寸的图标。

import win32ui
import win32gui
from PIL import Image

def get_exe_icon_with_size(exe_path, size=(32, 32)):
    # 获取exe文件的图标
    large, small = win32gui.ExtractIconEx(exe_path, 0)
    win32gui.DestroyIcon(small[0])

    # 创建一个设备上下文
    hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
    hbmp = win32ui.CreateBitmap()
    hbmp.CreateCompatibleBitmap(hdc, size[0], size[1])

    # 在设备上下文中绘制图标
    hdc = hdc.CreateCompatibleDC()
    hdc.SelectObject(hbmp)
    hdc.DrawIcon((0, 0), large[0])

    # 保存图标到本地文件
    bmpinfo = hbmp.GetInfo()
    bmpstr = hbmp.GetBitmapBits(True)
    img = Image.frombuffer(
        'RGB',
        (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
        bmpstr, 'raw', 'BGRX', 0, 1)
    img.save(f'icon_{size[0]}x{size[1]}.png')

# 示例:提取并保存64x64尺寸的图标
get_exe_icon_with_size(r'D:\install\Microsoft VS Code\Code.exe', size=(64, 64))

扩展4:处理错误和异常

在实际使用中,我们可能会遇到一些错误和异常。我们可以添加错误处理来提高代码的健壮性。

 

import win32ui
import win32gui
from PIL import Image

def get_exe_icon_safe(exe_path):
    try:
        # 获取exe文件的图标
        large, small = win32gui.ExtractIconEx(exe_path, 0)
        if not large:
            raise ValueError("无法提取图标")
        win32gui.DestroyIcon(small[0])

        # 创建一个设备上下文
        hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
        hbmp = win32ui.CreateBitmap()
        hbmp.CreateCompatibleBitmap(hdc, 32, 32)

        # 在设备上下文中绘制图标
        hdc = hdc.CreateCompatibleDC()
        hdc.SelectObject(hbmp)
        hdc.DrawIcon((0, 0), large[0])

        # 保存图标到本地文件
        bmpinfo = hbmp.GetInfo()
        bmpstr = hbmp.GetBitmapBits(True)
        img = Image.frombuffer(
            'RGB',
            (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
            bmpstr, 'raw', 'BGRX', 0, 1)
        img.save('icon.png')
        print("图标提取并保存成功")
    except Exception as e:
        print(f"发生错误: {e}")

get_exe_icon_safe(r'D:\install\Microsoft VS Code\Code

其他文章推荐

相关类型推荐

  • 使用Python进行图像处理
  • Python与Windows API的交互

结论

在这篇博客中,我们学习了如何使用Python和一些Windows特定的库从.exe文件中提取图标。虽然这个任务在某些情况下可能比较复杂,但是通过使用正确的工具和方法,我们可以轻松地完成它。

总结

通过本文的学习,你应该已经掌握了如何使用Python从.exe文件中提取图标,并将其保存为.png文件。如果你有任何问题或建议,请在评论区留言。        

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LIY若依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值