我正在使用 win32 api 尝试截取屏幕截图。一切正常,但颜色有些失真。
代码如下:
import cv2 as cv
import numpy as np
import win32gui, win32ui, win32con
def window_capture():
h = 1080
w = 1920
hwnd = None
wDC = win32gui.GetWindowDC(hwnd)
dcObj = win32ui.CreateDCFromHandle(wDC)
cDC = dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, w, h)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0, 0), (w, h), dcObj, (0, 0), win32con.SRCCOPY)
# dataBitMap.SaveBitmapFile(cDC, 'debug.bmp')
signedIntsArray = dataBitMap.GetBitmapBits(True)
# img = np.array(signedIntsArray).astype(dtype='uint8')
img = np.frombuffer(signedIntsArray, dtype='int8')
img.shape = (h,w,4)
# Free Resources
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
#img = img[...,:3]
img = np.ascontiguousarray(img)
return img
while True:
# Take screenshot
screenshot = window_capture() # fastest
cv.imshow("Computer Vision", screenshot)
if cv.waitKey(1) == ord('q'):
cv.destroyAllWindows()
break
我想要的是像左图这样的东西。但相反,我得到了正确的图像,带有所有这些颜色变形。任何人都可以告诉发生了什么事?我看到其他人也这样做,一切都很顺利。
您遇到的问题可能是由于 Win32 API 和 OpenCV 之间的颜色表示不同。 Win32 API 以 BGRA 格式(蓝色、绿色、红色、alpha)捕获颜色,而 OpenCV 以标准 BGR(蓝色、绿色、红色)格式读取图像。
解决此问题的一种方法是从捕获的图像中仅提取蓝色、绿色和红色通道,丢弃 alpha 通道。您可以通过修改代码中的以下行来执行此操作:
img = np.frombuffer(signedIntsArray, dtype='uint8')
img.shape = (h, w, 4)
img = img[..., :3]
这将只提取前三个颜色通道(BGR)并丢弃第四个通道(alpha)。
或者,您可以在显示之前使用 cv2.cvtColor 函数将图像从 BGRA 转换为 BGR:
screenshot = window_capture()[:, :, :3]
screenshot = cv2.cvtColor(screenshot, cv2.COLOR_BGRA2BGR)
cv2.imshow("Computer Vision", screenshot)
此代码首先仅从捕获的图像中提取前三个颜色通道 (BGR),然后使用 cv2.cvtColor 函数将图像从 BGRA 转换为 BGR。