You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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通道的处理不符合预期,也会影响颜色显示效果。

修改代码的两个关键位置即可解决问题:

  1. 将np.frombuffer(signedIntsArray, dtype='int8')改为np.frombuffer(signedIntsArray, dtype='uint8'),用无符号类型正确读取像素值。
  2. 取消注释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é

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 23:17:25