ImageGrab.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #
  2. # The Python Imaging Library
  3. # $Id$
  4. #
  5. # screen grabber (macOS and Windows only)
  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 == "win32":
  20. grabber = Image.core.grabscreen
  21. elif sys.platform == "darwin":
  22. import os
  23. import tempfile
  24. import subprocess
  25. else:
  26. raise ImportError("ImageGrab is macOS and Windows only")
  27. def grab(bbox=None, include_layered_windows=False, all_screens=False):
  28. if sys.platform == "darwin":
  29. fh, filepath = tempfile.mkstemp(".png")
  30. os.close(fh)
  31. subprocess.call(["screencapture", "-x", filepath])
  32. im = Image.open(filepath)
  33. im.load()
  34. os.unlink(filepath)
  35. if bbox:
  36. im = im.crop(bbox)
  37. else:
  38. offset, size, data = grabber(include_layered_windows, all_screens)
  39. im = Image.frombytes(
  40. "RGB",
  41. size,
  42. data,
  43. # RGB, 32-bit line padding, origin lower left corner
  44. "raw",
  45. "BGR",
  46. (size[0] * 3 + 3) & -4,
  47. -1,
  48. )
  49. if bbox:
  50. x0, y0 = offset
  51. left, top, right, bottom = bbox
  52. im = im.crop((left - x0, top - y0, right - x0, bottom - y0))
  53. return im
  54. def grabclipboard():
  55. if sys.platform == "darwin":
  56. fh, filepath = tempfile.mkstemp(".jpg")
  57. os.close(fh)
  58. commands = [
  59. 'set theFile to (open for access POSIX file "'
  60. + filepath
  61. + '" with write permission)',
  62. "try",
  63. " write (the clipboard as JPEG picture) to theFile",
  64. "end try",
  65. "close access theFile",
  66. ]
  67. script = ["osascript"]
  68. for command in commands:
  69. script += ["-e", command]
  70. subprocess.call(script)
  71. im = None
  72. if os.stat(filepath).st_size != 0:
  73. im = Image.open(filepath)
  74. im.load()
  75. os.unlink(filepath)
  76. return im
  77. else:
  78. data = Image.core.grabclipboard()
  79. if isinstance(data, bytes):
  80. from . import BmpImagePlugin
  81. import io
  82. return BmpImagePlugin.DibImageFile(io.BytesIO(data))
  83. return data