Python保存/访问文件扩展名图标并在Tkinter程序中使用它们

2024-04-16 19:49:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在尝试创建一些代码,这些代码将接受文件扩展名“.png”的输入,并返回系统上与该文件类型关联的图标。在

我使用的是python2.7.6和windows8。我已经找了几个小时的代码,通过从.exe文件中保存图像,但没有在注册表中找到文件扩展名并保存它。在

我发现了一些代码,可以让我把文件保存为一个bmp,它基本上是用wxpython的图标来位图工作,并保存图像。但是,我希望代码不使用wxpython,因为我使用Tkinter来编写接口本身。在

下面是当前从http://ginstrom.com/scribbles/2007/08/31/file-list-with-icons-on-wxpython-windows/开始工作的代码(稍作修改)

import wx
from win32com.shell import shell, shellcon
from win32con import FILE_ATTRIBUTE_NORMAL

def extension_to_bitmap(extension):
    """dot is mandatory in extension"""

    flags = shellcon.SHGFI_SMALLICON | \
            shellcon.SHGFI_ICON | \
            shellcon.SHGFI_USEFILEATTRIBUTES

    retval, info = shell.SHGetFileInfo(extension,
                         FILE_ATTRIBUTE_NORMAL,
                         flags)
    # non-zero on success
    assert retval

    hicon, iicon, attr, display_name, type_name = info

    # Get the bitmap
    icon = wx.EmptyIcon()
    icon.SetHandle(hicon)
    return wx.BitmapFromIcon(icon)

root = wx.App()

bitmapFile = extension_to_bitmap(".png")

bitmapFile.SaveFile('test.bmp', wx.BITMAP_TYPE_BMP)

非常感谢任何帮助!在


Tags: 文件代码图像importpngextensionwxpythonshell
3条回答

我最近不得不做一个类似的任务,我使用了以下命令(需要pywin32和PIL或pill)。基本上,你得到了图标的句柄,然后复制一个。这将返回一个PIL图像。如果需要,可以使用其他方法打开Icontemp.bmp。在

def icon32(PATH):
    SHGFI_ICON = 0x000000100
    SHGFI_ICONLOCATION = 0x000001000
    SHIL_EXTRALARGE = 0x00002
    ret, info = shell.SHGetFileInfo(PATH, 0, SHGFI_ICONLOCATION | SHGFI_ICON | SHIL_EXTRALARGE)
    hIcon, iIcon, dwAttr, name, typeName = info
    tempDirectory = os.getenv("temp")
    ico_x = win32api.GetSystemMetrics(win32con.SM_CXICON)
    #creating a destination memory DC
    hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
    hbmp = win32ui.CreateBitmap()
    hbmp.CreateCompatibleBitmap(hdc, ico_x, ico_x)
    hdc = hdc.CreateCompatibleDC()
    hdc.SelectObject(hbmp)
    hdc.DrawIcon((0, 0), hIcon)
    win32gui.DestroyIcon(hIcon)
    hbmp.SaveBitmapFile(hdc, tempDirectory + "\Icontemp.bmp")
    icon = QIcon(tempDirectory + "\Icontemp.bmp")
    os.remove(tempDirectory + "\Icontemp.bmp")
    return icon

灵感来自IronManMark20的答案。这个版本返回一个PIL映像,因此它不需要创建临时文件的磁盘I/O。它还可以获得不同的图像大小(见下文)有关更多信息,请查看this博客文章。在

from win32com.shell import shell, shellcon
from PIL import Image, ImageTk
import win32api
import win32con
import win32ui
import win32gui

def get_icon(PATH, size):
    SHGFI_ICON = 0x000000100
    SHGFI_ICONLOCATION = 0x000001000
    if size == "small":
        SHIL_SIZE = 0x00001
    elif size == "large":
        SHIL_SIZE = 0x00002
    else:
        raise TypeError("Invalid argument for 'size'. Must be equal to 'small' or 'large'")

    ret, info = shell.SHGetFileInfo(PATH, 0, SHGFI_ICONLOCATION | SHGFI_ICON | SHIL_SIZE)
    hIcon, iIcon, dwAttr, name, typeName = info
    ico_x = win32api.GetSystemMetrics(win32con.SM_CXICON)
    hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
    hbmp = win32ui.CreateBitmap()
    hbmp.CreateCompatibleBitmap(hdc, ico_x, ico_x)
    hdc = hdc.CreateCompatibleDC()
    hdc.SelectObject(hbmp)
    hdc.DrawIcon((0, 0), hIcon)
    win32gui.DestroyIcon(hIcon)

    bmpinfo = hbmp.GetInfo()
    bmpstr = hbmp.GetBitmapBits(True)
    img = Image.frombuffer(
        "RGBA",
        (bmpinfo["bmWidth"], bmpinfo["bmHeight"]),
        bmpstr, "raw", "BGRA", 0, 1
    )

    if size == "small":
        img = img.resize((16, 16), Image.ANTIALIAS)
    return img

Test Cases

奇怪的是,Python似乎没有多少创建/编辑*.ico文件的功能。听起来您的最佳选择是获取ImageMagick的Python绑定:

但是,我找不到任何与绑定相关的文档。从我所读到的,Python图像库(PIL)可以读取图标文件,但不能创建它们。但是,您可能可以使用PIL来创建位图文件:

相关问题 更多 >