Skip to content

Commit d5ed776

Browse files
author
BoboTiG
committed
Code review, add thanks
1 parent 9a1c4b1 commit d5ed776

3 files changed

Lines changed: 45 additions & 48 deletions

File tree

doc/THANKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
Many thanks to all those who helped (in no particular order):
22

33
Oros, Eownis, Sam from sametmax.com, sergey-vin, Alexander 'thehesiod' Mohr
4+
bubulle, anonyme from IndexError.net

doc/TODO

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
[OK] GNU/Linux: do not trust XML config files, use pure cpython
3+
[ ] GNU/Linux: optimize get_pixels(), use of XGetPixel() is too slow
34
[ ] Mac OSX: use pure ctype, no Quartz
45
[ ] Test ReactOS (should be the same as Windows)
56
[ ] Support for additional systems

mss.py

Lines changed: 43 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,42 @@ def get_pixels(self, monitor):
430430
431431
The XGetPixel() C code can be found at this URL:
432432
http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/ImUtil.c#n444
433+
434+
435+
@TODO: see if it is quicker than using XGetPixel().
436+
437+
1) C code as quick as XGetPixel() to translate into ctypes:
438+
439+
pixels = malloc(sizeof(unsigned char) * width * height * 3);
440+
for ( x = 0; x < width; ++x )
441+
for ( y = 0; y < height; ++y )
442+
offset = width * y * 3;
443+
addr = &(ximage->data)[y * ximage->bytes_per_line + (x << 2)];
444+
pixel = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
445+
pixels[x * 3 + offset] = (pixel & ximage->red_mask) >> 16;
446+
pixels[x * 3 + offset + 1] = (pixel & ximage->green_mask) >> 8;
447+
pixels[x * 3 + offset + 2] = pixel & ximage->blue_mask;
448+
449+
2) A first try in Python with ctypes
450+
451+
from ctypes import create_string_buffer, c_char
452+
rmask = ximage.contents.red_mask
453+
gmask = ximage.contents.green_mask
454+
bmask = ximage.contents.blue_mask
455+
bpl = ximage.contents.bytes_per_line
456+
buffer_len = width * height * 3
457+
xdata = ximage.contents.data
458+
data = cast(xdata, POINTER(c_char * buffer_len)).contents
459+
self.image = create_string_buffer(sizeof(c_char) * buffer_len)
460+
for x in range(width):
461+
for y in range(height):
462+
offset = width * y * 3
463+
addr = data[y * bpl + (x << 2)][0]
464+
pixel = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]
465+
self.image[x * 3 + offset] = (pixel & rmask) >> 16
466+
self.image[x * 3 + offset + 1] = (pixel & gmask) >> 8
467+
self.image[x * 3 + offset + 2] = pixel & bmask
468+
return self.image
433469
'''
434470

435471
width, height = monitor[b'width'], monitor[b'height']
@@ -446,62 +482,23 @@ def get_pixels(self, monitor):
446482
if not ximage:
447483
raise ScreenshotError('MSS: XGetImage() failed.')
448484

449-
'''
450-
C code as quick as XGetPixel() to translate into ctypes:
451-
452-
pixels = malloc(sizeof(unsigned char) * width * height * 3);
453-
454-
for ( x = 0; x < width; ++x )
455-
for ( y = 0; y < height; ++y )
456-
offset = width * y * 3;
457-
addr = &(ximage->data)[y * ximage->bytes_per_line + (x << 2)];
458-
pixel = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
459-
pixels[x * 3 + offset] = (pixel & ximage->red_mask) >> 16;
460-
pixels[x * 3 + offset + 1] = (pixel & ximage->green_mask) >> 8;
461-
pixels[x * 3 + offset + 2] = pixel & ximage->blue_mask;
462-
'''
463-
'''
464-
# @TODO: see if it is quicker than using XGetPixel().
465-
from ctypes import create_string_buffer, c_char, sizeof
466-
rmask = ximage.contents.red_mask
467-
gmask = ximage.contents.green_mask
468-
bmask = ximage.contents.blue_mask
469-
bpl = ximage.contents.bytes_per_line
470-
buffer_len = width * height * 3
471-
xdata = ximage.contents.data
472-
data = cast(xdata, POINTER(c_char * buffer_len)).contents
473-
self.image = create_string_buffer(sizeof(c_char) * buffer_len)
474-
xrange = getattr(__builtins__, 'xrange', range)
475-
for x in xrange(width):
476-
for y in xrange(height):
477-
offset = width * y * 3
478-
addr = data[y * bpl + (x << 2)][0]
479-
pixel = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]
480-
self.image[x * 3 + offset] = (pixel & rmask) >> 16
481-
self.image[x * 3 + offset + 1] = (pixel & gmask) >> 8
482-
self.image[x * 3 + offset + 2] = pixel & bmask
483-
return self.image
484-
'''
485-
486485
# @TODO: this part takes most of the time. Need a better solution.
487-
def pix(pixel, _resultats={}, b=pack):
486+
def pix(pixel, _resultats={}, _b=pack):
488487
''' Apply shifts to a pixel to get the RGB values.
489488
This method uses of memoization.
490489
'''
491490
if pixel not in _resultats:
492-
_resultats[pixel] = b(b'<B', (pixel & rmask) >> 16) + \
493-
b(b'<B', (pixel & gmask) >> 8) + b(b'<B', pixel & bmask)
491+
_resultats[pixel] = _b(b'<B', (pixel & rmask) >> 16) + \
492+
_b(b'<B', (pixel & gmask) >> 8) + _b(b'<B', pixel & bmask)
494493
return _resultats[pixel]
495494

496495
rmask = ximage.contents.red_mask
497496
gmask = ximage.contents.green_mask
498497
bmask = ximage.contents.blue_mask
499-
xrange = getattr(__builtins__, 'xrange', range)
500498
get_pix = self.xlib.XGetPixel
501499
pixels = [pix(get_pix(ximage, x, y))
502-
for y in xrange(height) for x in xrange(width)]
500+
for y in range(height) for x in range(width)]
503501
self.image = b''.join(pixels)
504-
505502
self.xlib.XDestroyImage(ximage)
506503
return self.image
507504

@@ -650,11 +647,9 @@ def mss(*args, **kwargs):
650647
instantiation.
651648
'''
652649

653-
mss_class = {
654-
'Darwin': MSSMac,
655-
'Linux': MSSLinux,
656-
'Windows': MSSWindows
657-
}[system()]
650+
mss_class = {'Darwin': MSSMac,
651+
'Linux': MSSLinux,
652+
'Windows': MSSWindows}[system()]
658653

659654
return mss_class(*args, **kwargs)
660655

0 commit comments

Comments
 (0)