asd
This commit is contained in:
@ -0,0 +1,76 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Gdk3-based screenshotting.
|
||||
|
||||
Adapted from https://stackoverflow.com/a/37768950/81636, but uses
|
||||
buffers directly instead of saving intermediate files (which is slow).
|
||||
"""
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from pyscreenshot.plugins.backend import CBackend
|
||||
from pyscreenshot.util import platform_is_osx
|
||||
|
||||
|
||||
class Gdk3BackendError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Gdk3PixbufWrapper(CBackend):
|
||||
name = "pygdk3"
|
||||
|
||||
def grab(self, bbox=None):
|
||||
"""Grabs an image directly to a buffer.
|
||||
|
||||
:param bbox: Optional tuple or list containing (x1, y1, x2, y2) coordinates
|
||||
of sub-region to capture.
|
||||
:return: PIL RGB image
|
||||
:raises: ValueError, if image data does not have 3 channels (RGB), each with 8
|
||||
bits.
|
||||
:rtype: Image
|
||||
"""
|
||||
if platform_is_osx():
|
||||
raise Gdk3BackendError("osx not supported")
|
||||
import gi # type: ignore
|
||||
|
||||
gi.require_version("Gdk", "3.0")
|
||||
# gi.require_version('GdkPixbuf', '2.0')
|
||||
from gi.repository import Gdk, GdkPixbuf # type: ignore
|
||||
|
||||
# read_pixel_bytes: New in version 2.32.
|
||||
if GdkPixbuf.PIXBUF_MAJOR == 2:
|
||||
if GdkPixbuf.PIXBUF_MINOR < 32:
|
||||
raise ValueError(
|
||||
"GdkPixbuf min supported version: 2.32 current:"
|
||||
+ GdkPixbuf.PIXBUF_VERSION
|
||||
)
|
||||
|
||||
w = Gdk.get_default_root_window()
|
||||
if bbox is not None:
|
||||
g = [bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]]
|
||||
else:
|
||||
g = w.get_geometry()
|
||||
pb = Gdk.pixbuf_get_from_window(w, *g)
|
||||
if not pb:
|
||||
raise Gdk3BackendError("empty buffer")
|
||||
|
||||
if pb.get_bits_per_sample() != 8:
|
||||
raise Gdk3BackendError("Expected 8 bits per pixel.")
|
||||
elif pb.get_n_channels() != 3:
|
||||
raise Gdk3BackendError("Expected RGB image.")
|
||||
|
||||
# Read the entire buffer into a python bytes object.
|
||||
# read_pixel_bytes: New in version 2.32.
|
||||
pixel_bytes = pb.read_pixel_bytes().get_data() # type: bytes
|
||||
width, height = g[2], g[3]
|
||||
|
||||
# Probably for SSE alignment reasons, the pixbuf has extra data in each line.
|
||||
# The args after "raw" help handle this; see
|
||||
# http://effbot.org/imagingbook/decoder.htm#the-raw-decoder
|
||||
return Image.frombytes(
|
||||
"RGB", (width, height), pixel_bytes, "raw", "RGB", pb.get_rowstride(), 1
|
||||
)
|
||||
|
||||
def backend_version(self):
|
||||
import gi
|
||||
|
||||
return ".".join(map(str, gi.version_info))
|
||||
Reference in New Issue
Block a user