使用Win32API截图出现颜色失真问题求助
问题
我正在使用Win32API尝试实现截图功能,代码运行正常,但截图存在颜色失真情况。期望得到色彩正常的截图,但实际得到的却是存在颜色畸变的截图,其他人采用相同操作却未出现此问题,想请教原因及解决办法。
以下是实现代码:
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
解决方案
颜色失真的核心原因有两个:
- 数据类型错误:你用
dtype='int8'读取Bitmap像素数据,但Win32返回的是无符号8位整数(0-255),用有符号的int8会把大于127的值转成负数(比如255变成-1),直接导致颜色数值异常。 - Alpha通道干扰:Win32的Bitmap是BGRA四通道格式,OpenCV的imshow对Alpha通道的处理不符合预期,也会影响颜色显示效果。
修改代码的两个关键位置即可解决问题:
- 将
np.frombuffer(signedIntsArray, dtype='int8')改为np.frombuffer(signedIntsArray, dtype='uint8'),用无符号类型正确读取像素值。 - 取消注释
img = img[...,:3],提取前三个BGR通道,去掉Alpha通道。
修改后的核心代码片段:
signedIntsArray = dataBitMap.GetBitmapBits(True) img = np.frombuffer(signedIntsArray, dtype='uint8') # 修正数据类型 img.shape = (h,w,4) # ... 资源释放代码 ... img = img[...,:3] # 去掉Alpha通道 img = np.ascontiguousarray(img)
额外建议:你当前硬编码了屏幕分辨率1920x1080,如果用户屏幕分辨率不同,会导致截图错位。可以改成动态获取屏幕分辨率:
# 替换硬编码的w和h import win32api # 需要新增导入 w = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) h = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)
内容的提问来源于stack exchange,提问作者André
相关产品推荐
相关产品推荐

