48 lines
No EOL
1.7 KiB
Python
48 lines
No EOL
1.7 KiB
Python
import numpy as np
|
|
import mss
|
|
|
|
try:
|
|
import bettercam as _bc
|
|
except ImportError:
|
|
_bc = None
|
|
|
|
|
|
class ScreenCapture:
|
|
"""Захват экрана. Использует bettercam (DXGI Desktop Duplication) -
|
|
он умеет захватывать эксклюзивный полноэкранный режим. Если bettercam
|
|
недоступен или не смог создать камеру, откатывается на mss."""
|
|
|
|
def __init__(self, output_idx=0):
|
|
self._cam = None
|
|
self._sct = None
|
|
if _bc is not None:
|
|
try:
|
|
self._cam = _bc.create(output_idx=output_idx, output_color="BGR")
|
|
except Exception:
|
|
self._cam = None
|
|
if self._cam is None:
|
|
self._sct = mss.mss()
|
|
|
|
@property
|
|
def backend(self):
|
|
return "bettercam" if self._cam else "mss"
|
|
|
|
def screen_size(self):
|
|
if self._cam:
|
|
return self._cam.width, self._cam.height
|
|
mon = self._sct.monitors[1]
|
|
return mon["width"], mon["height"]
|
|
|
|
def grab(self, region=None):
|
|
"""region = (left, top, right, bottom) в абсолютных координатах экрана.
|
|
Возвращает кадр BGR (numpy array) или None, если новый кадр недоступен."""
|
|
if self._cam:
|
|
return self._cam.grab(region=region)
|
|
|
|
if region is None:
|
|
mon = self._sct.monitors[1]
|
|
else:
|
|
left, top, right, bottom = region
|
|
mon = {"left": left, "top": top, "width": right - left, "height": bottom - top}
|
|
shot = np.asarray(self._sct.grab(mon))
|
|
return shot[:, :, :3] |