1

メモリにアイコン (RGB または PIL/Pillow 経由で必要な形式) があり、それを使用したい

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')

モードで読み込んLoadImageで正しく使用できる、書き込み可能な画像フォーマットが見つかりません。そのモードのファイルのみをサポートしIMAGE_ICONているようです。データを として読み戻すことはできますが、結果のハンドルは では使用できません。代わりにを に変換する方法はありますか? (記憶にある)LoadImageICOPNGBMPIMAGE_BITMAPShell_NotifyIconIMAGEHICON

4

1 に答える 1

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

パフォーマンスを気にする人にとって、より良い解決策はおそらくCreateDIBitmapまたはSetDIBitsを使用することです

より完全なコードは、このトレイ アイコン ラッパー クラスset_icon_from_dataのメソッドにあり、アルファ チャネルを独自のビットマップに分割して、透明な画像も適切に表示できるようにします。

于 2013-10-30T05:07:10.263 に答える