18834161486 发表于 2024-4-15 17:32

python前台和后台的几种截图函数

本帖最后由 18834161486 于 2024-4-16 12:38 编辑

一、前台截图
1、Pillow截图
import time
import cv2
import numpy as np
from PIL import ImageGrab

st = time.time()
screenshot = ImageGrab.grab(bbox=(0, 0, 1920, 1080))
screenshot = np.array(screenshot)
screenshot = cv2.cvtColor(screenshot, cv2.COLOR_RGB2BGR)
print(f'耗时:{time.time() - st}')
cv2.imshow('123', screenshot)
cv2.waitKey(0)
cv2.destroyAllWindows()

2、pyautogui截图
import time
import numpy as np
import pyautogui
import cv2

st = time.time()
pic = pyautogui.screenshot(region=(0, 0, 1920, 1080))
pic = np.array(pic)
pic = cv2.cvtColor(pic, cv2.COLOR_RGB2BGR)
print(f'耗时:{time.time() - st}')
cv2.imshow('456', np.array(pic))
cv2.waitKey(0)
cv2.destroyAllWindows()
3、mss截图
import time
import cv2
import numpy as np
from mss import mss

sct = mss()
st = time.time()
monitor = {'top': 0, 'left': 0, 'width': 1920, 'height': 1080}
screenshot = sct.grab(monitor)
img = np.array(screenshot)
img = cv2.cvtColor(img, cv2.COLOR_RGBA2RGB)
print(f'耗时:{time.time() - st}')
cv2.imshow("Screenshot", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
4、D3Dshot截图
import time
import cv2
import d3dshot

d3dshot = d3dshot.create()
st = time.time()
screenshot = d3dshot.screenshot()
image = cv2.cvtColor(screenshot, cv2.COLOR_RGB2BGR)
print(f'耗时:{time.time() - st}')
cv2.imshow("Screenshot", image)
cv2.waitKey(0)
d3dshot.stop()
cv2.destroyAllWindows()
二、后台截图
1、BitBlt截图
import time
from ctypes import windll, byref, c_ubyte
from ctypes.wintypes import RECT
import cv2
import numpy as np


def Capture(handle, x1=0, y1=0, x2=None, y2=None):
    '''
    后台截图
    :param handle: 句柄
    :param x1:
    :param y1:
    :param x2:
    :param y2:
    :return:
    '''
    GetDC = windll.user32.GetDC
    CreateCompatibleDC = windll.gdi32.CreateCompatibleDC
    GetClientRect = windll.user32.GetClientRect
    CreateCompatibleBitmap = windll.gdi32.CreateCompatibleBitmap
    SelectObject = windll.gdi32.SelectObject
    BitBlt = windll.gdi32.BitBlt
    SRCCOPY = 0x00CC0020
    GetBitmapBits = windll.gdi32.GetBitmapBits
    DeleteObject = windll.gdi32.DeleteObject
    ReleaseDC = windll.user32.ReleaseDC
    windll.user32.SetProcessDPIAware()
    r = RECT()
    GetClientRect(handle, byref(r))
    width, height = r.right, r.bottom
    if x2 is None:
      x2 = width
    if y2 is None:
      y2 = height
    dc = GetDC(handle)
    cdc = CreateCompatibleDC(dc)
    bitmap = CreateCompatibleBitmap(dc, x2 - x1, y2 - y1)
    SelectObject(cdc, bitmap)
    BitBlt(cdc, 0, 0, x2 - x1, y2 - y1, dc, x1, y1, SRCCOPY)
    total_bytes = (x2 - x1) * (y2 - y1) * 4
    buffer = bytearray(total_bytes)
    byte_array = c_ubyte * total_bytes
    GetBitmapBits(bitmap, total_bytes, byte_array.from_buffer(buffer))
    DeleteObject(bitmap)
    DeleteObject(cdc)
    ReleaseDC(handle, dc)
    return np.frombuffer(buffer, dtype=np.uint8).reshape(y2 - y1, x2 - x1, 4)


st = time.time()
pic = Capture(1706456, 0, 0, 1920, 1080)
print(f'耗时:{time.time() - st}')
cv2.imshow('123', pic)
cv2.waitKey(0)
cv2.destroyAllWindows()

2、PrintWindow截图
import time
import cv2
import numpy as np
from ctypes import windll
import win32gui
import win32ui

windll.user32.SetProcessDPIAware()


def capture(hwnd, x1, y1, x2, y2):
    w = x2 - x1
    h = y2 - y1
    hwnd_dc = win32gui.GetWindowDC(hwnd)
    mfc_dc = win32ui.CreateDCFromHandle(hwnd_dc)
    save_dc = mfc_dc.CreateCompatibleDC()
    bitmap = win32ui.CreateBitmap()
    bitmap.CreateCompatibleBitmap(mfc_dc, w, h)
    save_dc.SelectObject(bitmap)
    windll.user32.PrintWindow(hwnd, save_dc.GetSafeHdc(), 3)
    bmpinfo = bitmap.GetInfo()
    bmpstr = bitmap.GetBitmapBits(True)
    img = np.frombuffer(bmpstr, dtype=np.uint8).reshape((bmpinfo["bmHeight"], bmpinfo["bmWidth"], 4))
    win32gui.DeleteObject(bitmap.GetHandle())
    save_dc.DeleteDC()
    mfc_dc.DeleteDC()
    win32gui.ReleaseDC(hwnd, hwnd_dc)
    return img


st = time.time()
img = capture(1706456, 0, 0, 1920, 1080)
print(f'耗时:{time.time() - st}')
cv2.imshow("123", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

总结:前台D3Dshot截图比较快一点,但是频繁截图耗时基本一样。后台截图BitBlt截图比较快一点,但是不支持浏览器截图,PrintWindow截图慢,但是支持浏览器。
——————————————————————————————
20240416更新前台截图
dxcam截图
import time
import cv2
import dxcam

capture = dxcam.create()
st = time.time()
pic = capture.grab()
pic = cv2.cvtColor(pic, cv2.COLOR_RGB2BGR)
print(f'耗时:{time.time() - st}')
cv2.imshow('123', pic)
cv2.waitKey(0)
cv2.destroyAllWindows()
dxcam截图打败了d3dshot截图,暂居前台截图榜第一。

y5230024 发表于 2024-6-18 16:38

测试了一下,遮挡可以截图,最小化不行,还有就是运行时cv2.imshow报错显示 The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure
script in function 'cvShowImage,需要pip install opencv-contrib-python。

18834161486 发表于 2024-4-15 17:34

python版本:Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) on win32

ghoob321 发表于 2024-4-15 18:34


感谢分享

jtjt68 发表于 2024-4-15 18:35

感谢分享{:1_893:}

狂侠先森 发表于 2024-4-15 20:52

多谢分享 支持

zzhd 发表于 2024-4-15 21:19

感谢分享

01z8z0 发表于 2024-4-15 21:37


感谢分享。。。。。。。。。。。。

52PJ070 发表于 2024-4-16 03:03

很棒的原创分享,参考了,感谢!

wizarrr 发表于 2024-4-16 09:05

挺好的总结!谢谢

O2H2O 发表于 2024-4-16 10:58

给善于总结的人点赞!
页: [1] 2
查看完整版本: python前台和后台的几种截图函数