Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 4, 2025 18:33:44

Lord_Parsec
Зарегистрирован: 2025-01-30
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

win32gui.GetPixel возвращает неактуальные цвета

Пишу программу на питоне, необходимо считывать цвета пикселей с приложения. Код:

 def getPixel(alt, data):
    try:
        x, y = data
    except TypeError as e:
        print("Error: Wrong x, y data in getPixel")
        return None
    hwnd = alt.hwnd
    # win32gui.InvalidateRect(hwnd, None, True)
    # win32gui.UpdateWindow(hwnd)
    hdc = win32gui.GetDC(hwnd)
    if hdc == 0:
        print("Error: cant get HDC")
    color = None
    try:
        color = win32gui.GetPixel(int(x), int(y))
    except Exception as e:
        print(f"Error, cant get color: {e}")
    win32gui.ReleaseDC(hwnd, hdc)
    color = rgba(color)
    return color

У меня на все работает отлично, у нескольких друзей тоже. Но у остальных код перестает работать. При чем довольно своеобразным образом - нет никаких ошибок, функция возвращает цвет, вот только она не видит актуальные цвета окна. Буд то при запуске запоминается изображение, и вместо актуального цвета возвращается цвет, который был в том месте при запуске.
Возможно связано с виндой, ибо у меня 10, и пока у всех у кого эта проблема появилас - 11.
Как видно с кода, InvalidateRect и UpdateWindow уже пробовал. Так же пробовал через:
 hdc_window = win32gui.GetDC(hwnd)
    hdc_mem = win32ui.CreateDCFromHandle(win32gui.CreateCompatibleDC(hdc_window))
    
    bmp = win32ui.CreateBitmap()
    bmp.CreateCompatibleBitmap(win32ui.CreateDCFromHandle(hdc_window), width, height)
    hdc_mem.SelectObject(bmp)
    
    hdc_mem.BitBlt((0, 0), (width, height), win32ui.CreateDCFromHandle(hdc_window), (0, 0), win32con.SRCCOPY)
    bmp_info = bmp.GetInfo()
    bmp_str = bmp.GetBitmapBits(True)
    img = Image.frombuffer('RGB', (bmp_info['bmWidth'], bmp_info['bmHeight']), bmp_str, 'raw', 'BGRX', 0, 1)
    win32gui.ReleaseDC(hwnd, hdc_window)
    hdc_mem.DeleteDC()
    bmp_handle = bmp.GetHandle()
    win32gui.DeleteObject(bmp_handle)
- результат тот же.
Использовал ImageGrab.grab с Pilow, он видит актуальную картинку, но в отличии от методов выше он не может работать с перекрытым окном, что мне необходимо.
Так же по совету GPT отключил оптимизацию:
 DWM_BLURBEHIND = ctypes.Structure
DWMWA_USE_IMMERSIVE_DARK_MODE = 20  
DWMWA_FORCE_ICONIC_REPRESENTATION = 7
DWMWA_CLOAKED = 14
user32 = ctypes.windll.user32
dwmapi = ctypes.windll.dwmapi
def disable_dcomp(hwnd):
    value = wintypes.BOOL(False)
    dwmapi.DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, ctypes.byref(value), ctypes.sizeof(value))
    value = ctypes.c_int(0)  # DirectComposition
    dwmapi.DwmSetWindowAttribute(hwnd, DWMWA_CLOAKED, ctypes.byref(value), ctypes.sizeof(value))
def disableGDI(alt, data):
    DWMWA_FORCE_ICONIC_REPRESENTATION = 7
    DWMWA_CLOAKED = 14
    hwnd = alt.hwnd
    value = ctypes.c_int(0)  # Отключаем DirectComposition
    dwmapi.DwmSetWindowAttribute(hwnd, DWMWA_CLOAKED, ctypes.byref(value), ctypes.sizeof(value))
- помогло только у части пользователей.
Как решить эту проблему, или какую альтернативу посоветуете использовать?

Отредактировано Lord_Parsec (Фев. 4, 2025 18:47:54)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version