@@ -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