ImageGrab.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #
  2. # The Python Imaging Library
  3. # $Id$
  4. #
  5. # screen grabber
  6. #
  7. # History:
  8. # 2001-04-26 fl created
  9. # 2001-09-17 fl use builtin driver, if present
  10. # 2002-11-19 fl added grabclipboard support
  11. #
  12. # Copyright (c) 2001-2002 by Secret Labs AB
  13. # Copyright (c) 2001-2002 by Fredrik Lundh
  14. #
  15. # See the README file for information on usage and redistribution.
  16. #
  17. import sys
  18. from . import Image
  19. if sys.platform == "darwin":
  20. import os
  21. import subprocess
  22. import tempfile
  23. def grab(bbox=None, include_layered_windows=False, all_screens=False, xdisplay=None):
  24. if xdisplay is None:
  25. if sys.platform == "darwin":
  26. fh, filepath = tempfile.mkstemp(".png")
  27. os.close(fh)
  28. subprocess.call(["screencapture", "-x", filepath])
  29. im = Image.open(filepath)
  30. im.load()
  31. os.unlink(filepath)
  32. if bbox:
  33. im_cropped = im.crop(bbox)
  34. im.close()
  35. return im_cropped
  36. return im
  37. elif sys.platform == "win32":
  38. offset, size, data = Image.core.grabscreen_win32(
  39. include_layered_windows, all_screens
  40. )
  41. im = Image.frombytes(
  42. "RGB",
  43. size,
  44. data,
  45. # RGB, 32-bit line padding, origin lower left corner
  46. "raw",
  47. "BGR",
  48. (size[0] * 3 + 3) & -4,
  49. -1,
  50. )
  51. if bbox:
  52. x0, y0 = offset
  53. left, top, right, bottom = bbox
  54. im = im.crop((left - x0, top - y0, right - x0, bottom - y0))
  55. return im
  56. # use xdisplay=None for default display on non-win32/macOS systems
  57. if not Image.core.HAVE_XCB:
  58. raise OSError("Pillow was built without XCB support")
  59. size, data = Image.core.grabscreen_x11(xdisplay)
  60. im = Image.frombytes("RGB", size, data, "raw", "BGRX", size[0] * 4, 1)
  61. if bbox:
  62. im = im.crop(bbox)
  63. return im
  64. def grabclipboard():
  65. if sys.platform == "darwin":
  66. fh, filepath = tempfile.mkstemp(".jpg")
  67. os.close(fh)
  68. commands = [
  69. 'set theFile to (open for access POSIX file "'
  70. + filepath
  71. + '" with write permission)',
  72. "try",
  73. " write (the clipboard as JPEG picture) to theFile",
  74. "end try",
  75. "close access theFile",
  76. ]
  77. script = ["osascript"]
  78. for command in commands:
  79. script += ["-e", command]
  80. subprocess.call(script)
  81. im = None
  82. if os.stat(filepath).st_size != 0:
  83. im = Image.open(filepath)
  84. im.load()
  85. os.unlink(filepath)
  86. return im
  87. elif sys.platform == "win32":
  88. fmt, data = Image.core.grabclipboard_win32()
  89. if fmt == "file": # CF_HDROP
  90. import struct
  91. o = struct.unpack_from("I", data)[0]
  92. if data[16] != 0:
  93. files = data[o:].decode("utf-16le").split("\0")
  94. else:
  95. files = data[o:].decode("mbcs").split("\0")
  96. return files[: files.index("")]
  97. if isinstance(data, bytes):
  98. import io
  99. data = io.BytesIO(data)
  100. if fmt == "png":
  101. from . import PngImagePlugin
  102. return PngImagePlugin.PngImageFile(data)
  103. elif fmt == "DIB":
  104. from . import BmpImagePlugin
  105. return BmpImagePlugin.DibImageFile(data)
  106. return None
  107. else:
  108. raise NotImplementedError("ImageGrab.grabclipboard() is macOS and Windows only")