Skip to content

Commit 63fdfaa

Browse files
author
Mickaël Schoentgen
committed
MSS: accepts to same format as PIL.Image.grab
You can give a tuple(left, upper, right, lower) argument and it will be converted to the appropriate dict.
1 parent 9aca393 commit 63fdfaa

File tree

10 files changed

+142
-2
lines changed

10 files changed

+142
-2
lines changed

.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[MESSAGES CONTROL]
2-
disable = locally-disabled, too-few-public-methods, too-many-instance-attributes
2+
disable = locally-disabled, too-few-public-methods, too-many-instance-attributes, duplicate-code
33

44
[REPORTS]
55
output-format = colorized

docs/source/api.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ Methods
4343

4444
Retrieve screen pixels for a given monitor.
4545

46+
.. note::
47+
48+
``monitor`` can be a ``tuple`` like ``PIL.Image.grab()`` accepts,
49+
it will be converted to the approriate ``dict``.
50+
4651
.. method:: save(mon=1, output='screenshot.png', callback=None) -> generator
4752

4853
:param int mon: the monitor's number.
@@ -59,6 +64,8 @@ Methods
5964
Helper to save the screenshot of the first monitor, by default.
6065
You can pass the same arguments as for ``save``.
6166

67+
.. versionadded:: 3.0.0
68+
6269
.. class:: ScreenShot
6370

6471
Screen shot object.
@@ -86,6 +93,8 @@ Methods
8693

8794
Get the pixel value at the given position.
8895

96+
.. versionadded:: 3.0.0
97+
8998
.. module:: mss.tools
9099

91100
.. method:: to_png(data, size, output) -> None
@@ -97,6 +106,8 @@ Methods
97106

98107
Dump data to the image file. Pure Python PNG implementation.
99108

109+
.. versionadded:: 3.0.0
110+
100111

101112
Properties
102113
==========
@@ -179,6 +190,8 @@ Properties
179190

180191
:type: bytes
181192

193+
.. versionadded:: 3.0.0
194+
182195

183196
Exception
184197
=========

docs/source/examples.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ You can capture only a part of the screen:
4444
.. literalinclude:: examples/part_of_screen.py
4545
:lines: 9-
4646

47+
.. versionadded:: 3.0.0
48+
49+
Use PIL bbox style and percent values
50+
-------------------------------------
51+
52+
You can use the same value as you would do with ``PIL.ImageGrab(bbox=tuple(...))``.
53+
This is an example that uses it, but also using percentage values:
54+
55+
.. literalinclude:: examples/from_pil_tuple.py
56+
:lines: 9-
57+
58+
.. versionadded:: 3.1.0
59+
4760
Advanced
4861
========
4962

@@ -52,6 +65,8 @@ You can handle data using a custom class:
5265
.. literalinclude:: examples/custom_cls_image.py
5366
:lines: 9-
5467

68+
.. versionadded:: 3.1.0
69+
5570
PIL
5671
===
5772

@@ -61,6 +76,8 @@ This is an example using `frombytes() <http://pillow.readthedocs.io/en/latest/re
6176
.. literalinclude:: examples/pil.py
6277
:lines: 9-
6378

79+
.. versionadded:: 3.0.0
80+
6481
Playing with pixels
6582
-------------------
6683

@@ -69,6 +86,8 @@ This is an example using `putdata() <https://github.com/python-pillow/Pillow/blo
6986
.. literalinclude:: examples/pil_pixels.py
7087
:lines: 9-
7188

89+
.. versionadded:: 3.0.0
90+
7291
OpenCV/Numpy
7392
============
7493

@@ -79,6 +98,8 @@ And with __no__ lag please.
7998
.. literalinclude:: examples/opencv_numpy.py
8099
:lines: 9-
81100

101+
.. versionadded:: 3.0.0
102+
82103
FPS
83104
===
84105

@@ -89,3 +110,5 @@ Simple naive benchmark to compare with `Reading game frames in Python with OpenC
89110

90111
.. literalinclude:: examples/fps.py
91112
:lines: 12-
113+
114+
.. versionadded:: 3.0.0
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# coding: utf-8
2+
"""
3+
This is part of the MSS Python's module.
4+
Source: https://github.com/BoboTiG/python-mss
5+
6+
Use PIL bbox style and percent values.
7+
"""
8+
9+
import mss
10+
import mss.tools
11+
12+
13+
with mss.mss() as sct:
14+
# Use the 1st monitor
15+
monitor = sct.monitors[1]
16+
17+
# Capture a bbox using percent values
18+
left = monitor['left'] + monitor['width'] * 5 // 100 # 5% from the left
19+
top = monitor['top'] + monitor['height'] * 5 // 100 # 5% from the top
20+
right = left + 400 # 400px width
21+
lower = top + 400 # 400px height
22+
bbox = (left, top, right, lower)
23+
24+
# Grab the picture
25+
# Using PIL would be something like:
26+
# im = ImageGrab(bbox=bbox)
27+
im = sct.grab(bbox)
28+
29+
# Save it!
30+
mss.tools.to_png(im.rgb, im.size, 'screenshot.png')

mss/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ def monitors(self):
5757
'width': the width,
5858
'height': the height
5959
}
60+
61+
Note: monitor can be a tuple like PIL.Image.grab() accepts,
62+
it must be converted to the approriate dict.
6063
"""
6164

6265
raise NotImplementedError('Subclasses need to implement this!')

mss/darwin.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,15 @@ def grab(self, monitor):
174174
black pixels.
175175
"""
176176

177+
# Convert PIL bbox style
178+
if isinstance(monitor, tuple):
179+
monitor = {
180+
'left': monitor[0],
181+
'top': monitor[1],
182+
'width': monitor[2] - monitor[0],
183+
'height': monitor[3] - monitor[1],
184+
}
185+
177186
rounded_width = int(math.ceil(monitor['width'] // 16) * 16)
178187

179188
rect = CGRect((monitor['left'], monitor['top']),

mss/linux.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,15 @@ def grab(self, monitor):
273273
# type: (Dict[str, int]) -> ScreenShot
274274
""" Retrieve all pixels from a monitor. Pixels have to be RGB. """
275275

276+
# Convert PIL bbox style
277+
if isinstance(monitor, tuple):
278+
monitor = {
279+
'left': monitor[0],
280+
'top': monitor[1],
281+
'width': monitor[2] - monitor[0],
282+
'height': monitor[3] - monitor[1],
283+
}
284+
276285
# Fix for XGetImage:
277286
# expected LP_Display instance instead of LP_XWindowAttributes
278287
root = ctypes.cast(self.root, ctypes.POINTER(Display))

mss/windows.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,15 @@ def grab(self, monitor):
162162
Thanks to http://stackoverflow.com/a/3688682
163163
"""
164164

165+
# Convert PIL bbox style
166+
if isinstance(monitor, tuple):
167+
monitor = {
168+
'left': monitor[0],
169+
'top': monitor[1],
170+
'width': monitor[2] - monitor[0],
171+
'height': monitor[3] - monitor[1],
172+
}
173+
165174
srcdc = memdc = bmp = None
166175
try:
167176
bmi = BITMAPINFO()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
'classifiers': classifiers,
5454
'platforms': ['Darwin', 'Linux', 'Windows'],
5555
'packages': ['mss'],
56-
'license': 'MIT'
56+
'license': 'MIT',
5757
}
5858

5959
setup(**config)

tests/test_implementation.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pytest
99

1010
import mss
11+
import mss.tools
1112
from mss.base import MSSBase
1213
from mss.exception import ScreenShotError
1314
from mss.screenshot import ScreenShot
@@ -93,3 +94,46 @@ def raise_():
9394
with pytest.raises(ScreenShotError):
9495
mss.mss()
9596
monkeypatch.undo()
97+
98+
99+
def test_grab_with_tuple(sct):
100+
left = 100
101+
top = 100
102+
right = 500
103+
lower = 500
104+
width = right - left # 400px width
105+
height = lower - top # 400px height
106+
107+
# PIL like
108+
box = (left, top, right, lower)
109+
im = sct.grab(box)
110+
assert im.size == (width, height)
111+
112+
# MSS like
113+
box2 = {'left': left, 'top': top, 'width': width, 'height': height}
114+
im2 = sct.grab(box2)
115+
assert im.size == im2.size
116+
assert im.pos == im2.pos
117+
assert im.rgb == im2.rgb
118+
119+
120+
def test_grab_with_tuple_percents(sct):
121+
monitor = sct.monitors[1]
122+
left = monitor['left'] + monitor['width'] * 5 // 100 # 5% from the left
123+
top = monitor['top'] + monitor['height'] * 5 // 100 # 5% from the top
124+
right = left + 500 # 500px
125+
lower = top + 500 # 500px
126+
width = right - left
127+
height = lower - top
128+
129+
# PIL like
130+
box = (left, top, right, lower)
131+
im = sct.grab(box)
132+
assert im.size == (width, height)
133+
134+
# MSS like
135+
box2 = {'left': left, 'top': top, 'width': width, 'height': height}
136+
im2 = sct.grab(box2)
137+
assert im.size == im2.size
138+
assert im.pos == im2.pos
139+
assert im.rgb == im2.rgb

0 commit comments

Comments
 (0)