gpp207 2024-06-15 11:34 采纳率: 100%
浏览 547
已结题

BitBlt 和PrintWindow 截图为黑图的问题

请问为啥我用下面的代码对特定窗口进行截图的时候,当窗口为桌面或者文件夹的时候,保存的位图能够正常的显示,但是窗口变为网页或者其他的窗口的时候,保存的位图就变成了一张黑图,PrintWindow函数也试过,也是这种情况,请求大家帮忙解答指正 不甚感激。

img


img

import ctypes
import win32gui
import win32ui
import win32con

user32 = ctypes.windll.user32
gdi32 = ctypes.windll.gdi32

# 截图函数
def capture_window(hwnd):
    # 获取目标窗口的大小
    left, top, right, bot = win32gui.GetWindowRect(hwnd)
    width = right - left
    height = bot - top

    # 创建设备上下文
    hwndDC = win32gui.GetWindowDC(hwnd)
    mfcDC = win32ui.CreateDCFromHandle(hwndDC)
    saveDC = mfcDC.CreateCompatibleDC()

    saveBitMap = win32ui.CreateBitmap()
    saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)

    saveDC.SelectObject(saveBitMap)

    # 使用BitBlt代替PrintWindow
    saveDC.BitBlt((0, 0), (width, height), mfcDC, (0, 0), win32con.SRCCOPY)
    
    saveBitMap.SaveBitmapFile(saveDC, 'screenshot.bmp')

    # 清理
    win32gui.DeleteObject(saveBitMap.GetHandle())
    saveDC.DeleteDC()
    mfcDC.DeleteDC()
    win32gui.ReleaseDC(hwnd, hwndDC)

hwnd = 132452  # 将该值替换为实际窗口句柄
capture_window(hwnd)




  • 写回答

7条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-15 11:34
    关注

    引自免费微信小程序:皆我百晓生

    遇到使用BitBltPrintWindow截图时,某些窗口(如浏览器窗口)截取后呈现黑色的问题,这通常是因为这些窗口使用了透明度或双缓冲技术,而直接的GDI函数如BitBlt可能无法正确处理这些特性。

    解决此问题的一个常见方法是使用DirectX Surface截屏,但这种方法较为复杂且不适用于所有情况。另一种更通用的方案是利用Windows API的DwmCaptureSnapshot函数,该函数允许捕获包括透明效果在内的整个窗口快照。

    然而,由于你要求提供一个Python解决方案,并且希望避免过于复杂的操作,这里提供一种较为简单的替代方法:使用PIL(Python Imaging Library,现称为Pillow)库的屏幕抓取功能,它能够处理各种类型的窗口,包括那些使用了透明度或双缓冲的窗口。

    下面是使用Pillow库进行屏幕截图的示例代码:

    from PIL import ImageGrab
    import win32gui
    
    def capture_window(hwnd):
        # 获取窗口位置
        bbox = win32gui.GetWindowRect(hwnd)
        # 使用ImageGrab抓取窗口区域
        img = ImageGrab.grab(bbox)
        # 保存图像
        img.save('screenshot.png')
    
    # 替换hwnd为你想要截图的窗口句柄
    hwnd = 132452
    capture_window(hwnd)
    

    这段代码中,ImageGrab.grab()函数会根据给定的边界框捕获屏幕的一部分,而这个边界框正是由win32gui.GetWindowRect()获取的窗口位置和大小。这样,无论窗口是否使用了透明度或双缓冲,Pillow都能够正确地捕获其内容并保存为图像。

    请注意,使用Pillow之前,需要确保已经安装了该库。如果没有安装,可以通过运行pip install pillow命令来安装。

    这种方法虽然简单,但在大多数情况下都能有效解决问题,特别是当涉及到具有复杂渲染效果的现代应用程序时。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 6月23日
  • 已采纳回答 6月15日
  • 创建了问题 6月15日