2013-10-29 817 views
1

我在存储器(RGB或任何格式我经由PIL /枕头想要的)的图标和我想与Shell_NotifyIcon

win32gui.Shell_NotifyIcon 

这需要一个HICON使用它。 如何将RGB像素放入HICON?

或者,即使那是浪费的,我甚至不会介意通过临时文件做一个来回,并使用win32gui.LoadImage,像这样重装吧:

from PIL import Image 
#create example image with empty pixels: 
img = Image.frombuffer("RGB", (32, 32), "\0"*32*32*3, "raw", "RGB", 0, 1) 
img = img.convert("P") 
img = img.resize((64, 64), Image.ANTIALIAS) 
img.save("C:\\temp.ico", format="bmp") 
import win32gui, win32api, win32con 
flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE 
win32gui.LoadImage(None, "C:\\temp.ico", win32con.IMAGE_ICON, 0, 0, flags) 

但这种失败:pywintypes.error: (0, 'LoadImage', 'No error message available')

我只是找不到可以写入的图片格式,然后可以在IMAGE_ICON模式下通过​​正确读回并正确使用。看来​​只支持ICO这种模式下的文件:我可以回读PNGBMP数据为IMAGE_BITMAP,但生成的句柄不能被Shell_NotifyIcon使用。 有没有办法将IMAGE转换为HICON? (内存)

+0

我认为传递给'LoadImage'的第三个参数应该是'win32con.IMAGE_BITMAP'。 – martineau

+0

如果你阅读完整的文章,你会发现,当使用'IMAGE_BITMAP''时,'Shell_NotifyIcon'不能使用结果句柄。 – totaam

+0

对不起。我读了一些说:“我不知道这是否适用于所有情况,但在WinXP上,.ico可以是16x16,32x32或64x64大小的bmp。只需将扩展名从bmp更改为ico,即可准备好走。” – martineau

回答

1

我不知道我怎么错过了,但有一个叫CreateIcon函数,它接受的像素数据作为输入,虽然这个人是从pywin32的win32gui失踪,有一个CreateIconIndirect相反,这是一样好。

所以代码变得简单(仍在使用临时文件):

img = win32gui.LoadImage(None, "C:\\tmp.bmp", win32con.IMAGE_BITMAP, 0, 0, flags) 
pyiconinfo = (True, 0, 0, img, img) 
hicon = win32gui.CreateIconIndirect(pyiconinfo) 

要获得从PIL图像为位图RGB像素不使用临时文件,我用这个代码(是的,这是非常缓慢的做这种方式,但它是比较简单的,易于阅读,我真的不能在这种情况下,不太关心性能):

def img_to_bitmap(image, pixel_value): 
    hdc = win32gui.CreateCompatibleDC(0) 
    dc = win32gui.GetDC(0) 
    hbm = win32gui.CreateCompatibleBitmap(dc, size, size) 
    hbm_save = win32gui.SelectObject(hdc, hbm) 
    for x in range(size): 
     for y in range(size): 
      pixel = image.getpixel((x, y)) 
      v = pixel_value(pixel) 
      win32gui.SetPixelV(hdc, x, y, v) 
    win32gui.SelectObject(hdc, hbm_save) 
    win32gui.ReleaseDC(self.hwnd, hdc) 
    win32gui.ReleaseDC(self.hwnd, dc) 
    return hbm 

对于那些关心性能,更好的解决方案可能涉及CreateDIBitmapSetDIBits

现在可以在set_icon_from_data方法this tray icon wrapper class中找到更完整的代码,它处理将alpha通道分割为其自己的位图,以便我们也可以正确显示透明图像。

相关问题