aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/PIL/ImageGrab.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/PIL/ImageGrab.py')
-rw-r--r--.venv/lib/python3.12/site-packages/PIL/ImageGrab.py183
1 files changed, 183 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/PIL/ImageGrab.py b/.venv/lib/python3.12/site-packages/PIL/ImageGrab.py
new file mode 100644
index 00000000..fe27bfae
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/PIL/ImageGrab.py
@@ -0,0 +1,183 @@
+#
+# The Python Imaging Library
+# $Id$
+#
+# screen grabber
+#
+# History:
+# 2001-04-26 fl created
+# 2001-09-17 fl use builtin driver, if present
+# 2002-11-19 fl added grabclipboard support
+#
+# Copyright (c) 2001-2002 by Secret Labs AB
+# Copyright (c) 2001-2002 by Fredrik Lundh
+#
+# See the README file for information on usage and redistribution.
+#
+from __future__ import annotations
+
+import io
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+
+from . import Image
+
+
+def grab(
+ bbox: tuple[int, int, int, int] | None = None,
+ include_layered_windows: bool = False,
+ all_screens: bool = False,
+ xdisplay: str | None = None,
+) -> Image.Image:
+ im: Image.Image
+ if xdisplay is None:
+ if sys.platform == "darwin":
+ fh, filepath = tempfile.mkstemp(".png")
+ os.close(fh)
+ args = ["screencapture"]
+ if bbox:
+ left, top, right, bottom = bbox
+ args += ["-R", f"{left},{top},{right-left},{bottom-top}"]
+ subprocess.call(args + ["-x", filepath])
+ im = Image.open(filepath)
+ im.load()
+ os.unlink(filepath)
+ if bbox:
+ im_resized = im.resize((right - left, bottom - top))
+ im.close()
+ return im_resized
+ return im
+ elif sys.platform == "win32":
+ offset, size, data = Image.core.grabscreen_win32(
+ include_layered_windows, all_screens
+ )
+ im = Image.frombytes(
+ "RGB",
+ size,
+ data,
+ # RGB, 32-bit line padding, origin lower left corner
+ "raw",
+ "BGR",
+ (size[0] * 3 + 3) & -4,
+ -1,
+ )
+ if bbox:
+ x0, y0 = offset
+ left, top, right, bottom = bbox
+ im = im.crop((left - x0, top - y0, right - x0, bottom - y0))
+ return im
+ # Cast to Optional[str] needed for Windows and macOS.
+ display_name: str | None = xdisplay
+ try:
+ if not Image.core.HAVE_XCB:
+ msg = "Pillow was built without XCB support"
+ raise OSError(msg)
+ size, data = Image.core.grabscreen_x11(display_name)
+ except OSError:
+ if (
+ display_name is None
+ and sys.platform not in ("darwin", "win32")
+ and shutil.which("gnome-screenshot")
+ ):
+ fh, filepath = tempfile.mkstemp(".png")
+ os.close(fh)
+ subprocess.call(["gnome-screenshot", "-f", filepath])
+ im = Image.open(filepath)
+ im.load()
+ os.unlink(filepath)
+ if bbox:
+ im_cropped = im.crop(bbox)
+ im.close()
+ return im_cropped
+ return im
+ else:
+ raise
+ else:
+ im = Image.frombytes("RGB", size, data, "raw", "BGRX", size[0] * 4, 1)
+ if bbox:
+ im = im.crop(bbox)
+ return im
+
+
+def grabclipboard() -> Image.Image | list[str] | None:
+ if sys.platform == "darwin":
+ p = subprocess.run(
+ ["osascript", "-e", "get the clipboard as «class PNGf»"],
+ capture_output=True,
+ )
+ if p.returncode != 0:
+ return None
+
+ import binascii
+
+ data = io.BytesIO(binascii.unhexlify(p.stdout[11:-3]))
+ return Image.open(data)
+ elif sys.platform == "win32":
+ fmt, data = Image.core.grabclipboard_win32()
+ if fmt == "file": # CF_HDROP
+ import struct
+
+ o = struct.unpack_from("I", data)[0]
+ if data[16] != 0:
+ files = data[o:].decode("utf-16le").split("\0")
+ else:
+ files = data[o:].decode("mbcs").split("\0")
+ return files[: files.index("")]
+ if isinstance(data, bytes):
+ data = io.BytesIO(data)
+ if fmt == "png":
+ from . import PngImagePlugin
+
+ return PngImagePlugin.PngImageFile(data)
+ elif fmt == "DIB":
+ from . import BmpImagePlugin
+
+ return BmpImagePlugin.DibImageFile(data)
+ return None
+ else:
+ if os.getenv("WAYLAND_DISPLAY"):
+ session_type = "wayland"
+ elif os.getenv("DISPLAY"):
+ session_type = "x11"
+ else: # Session type check failed
+ session_type = None
+
+ if shutil.which("wl-paste") and session_type in ("wayland", None):
+ args = ["wl-paste", "-t", "image"]
+ elif shutil.which("xclip") and session_type in ("x11", None):
+ args = ["xclip", "-selection", "clipboard", "-t", "image/png", "-o"]
+ else:
+ msg = "wl-paste or xclip is required for ImageGrab.grabclipboard() on Linux"
+ raise NotImplementedError(msg)
+
+ p = subprocess.run(args, capture_output=True)
+ if p.returncode != 0:
+ err = p.stderr
+ for silent_error in [
+ # wl-paste, when the clipboard is empty
+ b"Nothing is copied",
+ # Ubuntu/Debian wl-paste, when the clipboard is empty
+ b"No selection",
+ # Ubuntu/Debian wl-paste, when an image isn't available
+ b"No suitable type of content copied",
+ # wl-paste or Ubuntu/Debian xclip, when an image isn't available
+ b" not available",
+ # xclip, when an image isn't available
+ b"cannot convert ",
+ # xclip, when the clipboard isn't initialized
+ b"xclip: Error: There is no owner for the ",
+ ]:
+ if silent_error in err:
+ return None
+ msg = f"{args[0]} error"
+ if err:
+ msg += f": {err.strip().decode()}"
+ raise ChildProcessError(msg)
+
+ data = io.BytesIO(p.stdout)
+ im = Image.open(data)
+ im.load()
+ return im