2013-10-29 23 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通道分割爲其自己的位圖,以便我們也可以正確顯示透明圖像。

相關問題