11# coding: utf-8
2- """ This is part of the MSS Python's module.
3- Source: https://github.com/BoboTiG/python-mss
2+ """
3+ This is part of the MSS Python's module.
4+ Source: https://github.com/BoboTiG/python-mss
45"""
56
67# pylint: disable=import-error
78
9+ from __future__ import division
10+
811import ctypes
912import ctypes .util
1013import math
@@ -153,12 +156,13 @@ def grab(self, monitor):
153156 """
154157 See :meth:`MSSBase.grab <mss.base.MSSBase.grab>` for full details.
155158
156- When the monitor width is not divisible by 16, extra padding is
157- added by macOS in the form of black pixels, which results
158- in a screenshot with shifted pixels.
159+ When the monitor width is not divisible by 16, its width is reduced
160+ to the previous number divisible by 16. So we need to add extra
161+ black pixels.
159162 """
160163
161- rounded_width = math .ceil (monitor ['width' ] / 16 ) * 16
164+ rounded_width = int (math .ceil (monitor ['width' ] // 16 ) * 16 )
165+
162166 rect = CGRect ((monitor ['left' ], monitor ['top' ]),
163167 (rounded_width , monitor ['height' ]))
164168
@@ -177,8 +181,28 @@ def grab(self, monitor):
177181 data = data .contents
178182 self .core .CGDataProviderRelease (prov )
179183
180- # The width is rounded to 16, so we can have resulting images with a
181- # lesser width than requested.
182- monitor ['width' ], monitor ['height' ] = width , height
184+ if rounded_width != monitor ['width' ]:
185+ data = self .resize (data , monitor )
186+
187+ if len (data ) != monitor ['width' ] * monitor ['height' ] * 4 :
188+ del data
189+ raise ScreenShotError ('Data length mismatch.' , locals ())
183190
184191 return ScreenShot (data , monitor )
192+
193+ @staticmethod
194+ def resize (data , monitor ):
195+ # type: (bytearray, Dict[str, int]) -> bytearray
196+ """ Extend a 16 width-rounded screenshot to its original width. """
197+
198+ rounded_width = int (math .ceil (monitor ['width' ] // 16 ) * 16 )
199+ cropped = bytearray ()
200+
201+ for row in range (monitor ['height' ]):
202+ start = row * rounded_width * 4
203+ end = start + monitor ['width' ] * 4
204+ cropped .extend (data [start :end ])
205+
206+ cropped .extend (b'\00 ' * (monitor ['width' ] - rounded_width ) * 4 )
207+
208+ return cropped
0 commit comments