用Pywin32拍摄的屏幕截图有时会出现黑色图片,我认为这个手柄不合适

2024-09-24 22:17:58 发布

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

def window_full_shot(hwnd, gray=0):
    hwnd = get_hwnd(hwnd)[0]
    print(hwnd)
    print(win32gui.GetClassName(hwnd))
    l, t, r, b = win32gui.GetWindowRect(hwnd)
    h = b - t
    w = r - l
    hwindc = win32gui.GetWindowDC(hwnd)
    srcdc = win32ui.CreateDCFromHandle(hwindc)
    memdc = srcdc.CreateCompatibleDC()
    bmp = win32ui.CreateBitmap()
    bmp.CreateCompatibleBitmap(srcdc, w, h)
    memdc.SelectObject(bmp)
    memdc.BitBlt((0, 0), (w, h), srcdc, (0, 0), win32con.SRCCOPY)

    signedIntsArray = bmp.GetBitmapBits(True)
    img = np.fromstring(signedIntsArray, dtype='uint8')
    img.shape = (h, w, 4)
    print(type(img))
    srcdc.DeleteDC()
    memdc.DeleteDC()
    win32gui.ReleaseDC(hwnd, hwindc)
    win32gui.DeleteObject(bmp.GetHandle())
    if gray == 0:
        return cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
    else:
        return cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)

我用这个代码拍了两个窗口,一个可以得到一个正确的img,另一个不行,就像那样。 the right codethe bad code


Tags: imgreturncv2printwin32guibmpgrayhwnd
1条回答
网友
1楼 · 发布于 2024-09-24 22:17:58

应用程序的框架,如电子应用程序,QT,WPF。。。将打印黑屏以响应GetDCGetWindowDC。你知道吗

唯一的解决方法是确保目标应用程序可见,并在目标应用程序所在的特定坐标处拍摄桌面截图。

Windows GDI函数通常忽略alpha通道。但是如果您以32位检索屏幕截图,那么GetDIBits会将所有alpha值设置为255(至少在windows10中是这样)。你知道吗

关于代码示例(C++),请参阅:{{a1}

Python代码:

import win32gui
import win32ui
import win32con
from ctypes import windll
from PIL import Image
import time
import ctypes

hwnd_target = win32gui.FindWindow(None, 'Calculator') # used for test 

left, top, right, bot = win32gui.GetWindowRect(hwnd_target)
w = right - left
h = bot - top

win32gui.SetForegroundWindow(hwnd_target)
time.sleep(1.0)

hdesktop = win32gui.GetDesktopWindow()
hwndDC = win32gui.GetWindowDC(hdesktop)
mfcDC  = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()

saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)

saveDC.SelectObject(saveBitMap)

result = saveDC.BitBlt((0, 0), (w, h), mfcDC, (left, top), win32con.SRCCOPY)

bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)

im = Image.frombuffer(
    'RGB',
    (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
    bmpstr, 'raw', 'BGRX', 0, 1)

win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hdesktop, hwndDC)

if result == None:
    #PrintWindow Succeeded
    im.save("test.png")

相关问题 更多 >