@@ -65,7 +65,7 @@ class XWindowAttributes(Structure):
65
65
66
66
class XImage (Structure ):
67
67
_fields_ = [('width' , c_int ), ('height' , c_int ), ('xoffset' , c_int ),
68
- ('format' , c_int ), ('data' , c_char_p ),
68
+ ('format' , c_int ), ('data' , c_void_p ),
69
69
('byte_order' , c_int ), ('bitmap_unit' , c_int ),
70
70
('bitmap_bit_order' , c_int ), ('bitmap_pad' , c_int ),
71
71
('depth' , c_int ), ('bytes_per_line' , c_int ),
@@ -349,7 +349,7 @@ def _set_argtypes(self):
349
349
self .xlib .XGetImage .argtypes = [POINTER (Display ), POINTER (Display ),
350
350
c_int , c_int , c_uint , c_uint , c_ulong ,
351
351
c_int ]
352
- self .xlib .XGetPixel .argtypes = [POINTER (XImage ), c_int , c_int ]
352
+ # self.xlib.XGetPixel.argtypes = [POINTER(XImage), c_int, c_int]
353
353
self .xlib .XDestroyImage .argtypes = [POINTER (XImage )]
354
354
self .xlib .XCloseDisplay .argtypes = [POINTER (Display )]
355
355
self .xrandr .XRRGetScreenResources .argtypes = [POINTER (Display ),
@@ -370,7 +370,7 @@ def _set_restypes(self):
370
370
self .xlib .XGetWindowAttributes .restype = c_int
371
371
self .xlib .XAllPlanes .restype = c_ulong
372
372
self .xlib .XGetImage .restype = POINTER (XImage )
373
- self .xlib .XGetPixel .restype = c_ulong
373
+ # self.xlib.XGetPixel.restype = c_ulong
374
374
self .xlib .XDestroyImage .restype = c_void_p
375
375
self .xlib .XCloseDisplay .restype = c_void_p
376
376
self .xlib .XDefaultRootWindow .restype = POINTER (XWindowAttributes )
@@ -427,33 +427,61 @@ def get_pixels(self, monitor):
427
427
if not ximage :
428
428
raise ScreenshotError ('MSS: XGetImage() failed.' )
429
429
430
- from ctypes import c_ubyte , c_char
430
+ '''
431
+ pixels = malloc(sizeof(unsigned char) * width * height * 3);
432
+
433
+ for ( x = 0; x < width; ++x )
434
+ for ( y = 0; y < height; ++y )
435
+ offset = width * y * 3;
436
+ //~ pixel = XGetPixel(ximage, x, y);
437
+ addr = &(ximage->data)[y * ximage->bytes_per_line + (x << 2)];
438
+ pixel = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
439
+ pixels[x * 3 + offset] = (pixel & ximage->red_mask) >> 16;
440
+ pixels[x * 3 + offset + 1] = (pixel & ximage->green_mask) >> 8;
441
+ pixels[x * 3 + offset + 2] = pixel & ximage->blue_mask;
442
+ '''
443
+ """from ctypes import create_string_buffer, c_char, sizeof
444
+ rmask = ximage.contents.red_mask
445
+ gmask = ximage.contents.green_mask
446
+ bmask = ximage.contents.blue_mask
431
447
bpl = ximage.contents.bytes_per_line
432
- data = cast (ximage .contents .data , POINTER (width * height * c_ubyte )).contents
433
-
448
+ data = cast(ximage.contents.data, POINTER(c_char * width * height * 3)).contents
449
+ self.image = create_string_buffer(sizeof(c_char) * width * height * 3)
450
+ xrange = getattr(__builtins__, 'xrange', range)
451
+ for x in xrange(width):
452
+ for y in xrange(height):
453
+ offset = width * y * 3
454
+ addr = data[y * bpl + (x << 2)][0]
455
+ pixel = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]
456
+ self.image[x * 3 + offset] = (pixel & rmask) >> 16
457
+ self.image[x * 3 + offset + 1] = (pixel & gmask) >> 8
458
+ self.image[x * 3 + offset + 2] = pixel & bmask
459
+ #~ self.image[x * 3 + offset:x * 3 + offset + 2] = \
460
+ #~ (pixel & rmask) >> 16, (pixel & gmask) >> 8, pixel & bmask
461
+
462
+ """
434
463
# @TODO: this part takes most of the time. Need a better solution.
435
464
def pix (pixel , _resultats = {}, b = pack ):
436
465
''' Apply shifts to a pixel to get the RGB values.
437
466
This method uses of memoization.
438
467
'''
439
468
if pixel not in _resultats :
440
- _resultats [pixel ] = b (b'<B' , pixel >> 24 ) + \
441
- b (b'<B' , pixel >> 16 ) + b (b'<B' , pixel )
469
+ _resultats [pixel ] = b (b'<B' , ( pixel & rmask ) >> 16 ) + \
470
+ b (b'<B' , ( pixel & gmask ) >> 8 ) + b (b'<B' , pixel & bmask )
442
471
return _resultats [pixel ]
443
472
444
473
# http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/ImUtil.c#n444
445
- #~ get_pix = self.xlib.XGetPixel
446
- #~ def get_pix(x, y):
447
-
474
+ xrange = getattr (__builtins__ , 'xrange' , range )
448
475
rmask = ximage .contents .red_mask
449
476
gmask = ximage .contents .green_mask
450
477
bmask = ximage .contents .blue_mask
451
- bpl = ximage .contents .bytes_per_line
452
- xrange = getattr (__builtins__ , 'xrange' , range )
453
- pixels = [pix (data [idx ])
454
- for idx in xrange (0 , (width * height ) - 2 , 3 )]
455
- self .xlib .XDestroyImage (ximage )
478
+ get_pix = self .xlib .XGetPixel
479
+ pixels = [pix (get_pix (ximage , x , y ))
480
+ for y in range (height ) for x in range (width )]
456
481
self .image = b'' .join (pixels )
482
+ #"""
483
+
484
+ self .xlib .XDestroyImage (ximage )
457
485
return self .image
458
486
459
487
0 commit comments