from bibliopixel.animation.matrix import Matrix
from bibliopixel.util import log
import numpy as np
try:
import cv2
except ImportError:
log.error('Could not import cv2 library')
import os
grab = None
if os.name == 'nt':
try:
from desktopmagic.screengrab_win32 import getRectAsImage, getScreenAsImage
log.debug("Using desktopmagic module")
def nt_grab(bbox=None):
if bbox is None:
img = getScreenAsImage()
else:
img = getRectAsImage(bbox)
return img
grab = nt_grab
except Exception:
pass
if grab is None:
try:
from mss.linux import MSS as mss
from PIL import Image
sct = mss()
monitor = sct.monitors[0]
def mss_grab(bbox):
sct_img = sct.grab(monitor)
img = Image.frombytes('RGBA', sct_img.size, bytes(sct_img.raw), 'raw', 'BGRA').crop(bbox)
img = img.convert('RGB')
return img
grab = mss_grab
log.debug('Using mss module')
except Exception:
try:
from PIL import ImageGrab
grab = ImageGrab.grab
log.debug("Using PIL ImageGrab module")
except Exception:
try:
import pyscreenshot as ImageGrab
grab = ImageGrab.grab
log.debug("Using pyscreenshot module")
except Exception:
log.error("Unable to find any available screenshot option.")
grab = None
[docs]class ScreenGrab(Matrix):
def __init__(self, layout, bbox=(300, 300, 332, 332), mirror=False,
offset=0.0, crop=True, **kwds):
super().__init__(layout, **kwds)
if not sum(bbox):
bbox = None
self.bbox = bbox
self.crop = crop
self.mirror = mirror
self.image = frame = self._capFrame()
self._iw = frame.shape[1]
self._ih = frame.shape[0]
self.width = self.width
self.height = self.height
# self._scale = (self.height*1.0//self._ih)
self._cropY = 0
self._cropX = 0
xoffset = yoffset = offset
if xoffset > 1.0:
xoffset = 1.0
elif xoffset < -1.0:
xoffset = -1.0
if yoffset > 1.0:
yoffset = 1.0
elif yoffset < -1.0:
yoffset = -1.0
xoffset += 1.0
yoffset += 1.0
if self.height >= self.width:
self._cropX = (self._iw - int(self.width / (self.height / float(self._ih)))) // 2
if self._ih >= self._iw:
scale = (self.height * 1.0) // self._ih
else:
scale = (self.width * 1.0) // self._iw
else:
self._cropY = (self._ih - int(self.height / (self.width / float(self._iw)))) // 2
if self._ih >= self._iw:
scale = (self.width * 1.0) // self._iw
else:
scale = (self.height * 1.0) // self._ih
scaleW = int(self.width / scale)
scaleH = int(self.height / scale)
padTB = (scaleH - self._ih) // 2
padLR = (scaleW - self._iw) // 2
padYoff = int(round(padTB * yoffset)) - padTB
padXoff = int(round(padLR * xoffset)) - padLR
self._pad = (padTB + padYoff, padTB - padYoff,
padLR + padXoff, padLR - padXoff)
self.xoff = int(round(self._cropX * xoffset)) - self._cropX
self.yoff = int(round(self._cropY * yoffset)) - self._cropY
def _capFrame(self):
img = grab(self.bbox)
return np.array(img)
[docs] def step(self, amt=1):
image = self._capFrame()
if self.crop:
image = image[self._cropY + self.yoff:self._ih - self._cropY +
self.yoff, self._cropX + self.xoff:self._iw - self._cropX + self.xoff]
else:
t, b, l, r = self._pad
image = cv2.copyMakeBorder(
image, t, b, l, r, cv2.BORDER_CONSTANT, value=[0, 0, 0])
resized = cv2.resize(image, (self.width, self.height),
interpolation=cv2.INTER_LINEAR)
if self.mirror:
resized = cv2.flip(resized, 1)
for y in range(self.height):
for x in range(self.width):
self.layout.set(x, y, tuple(resized[y, x][0:3]))