1+ """
2+ Original screenshot utilities from arcade 2.
3+
4+ These functions are flawed because they only read from the screen.
5+ """
6+
17from typing import Optional
28
39import PIL .Image
410import PIL .ImageOps
5- from pyglet import gl
611
712from arcade .window_commands import get_window
813
@@ -22,34 +27,43 @@ def get_pixel(x: int, y: int, components: int = 3) -> tuple[int, ...]:
2227 # The window may be 'scaled' on hi-res displays. Particularly Macs. OpenGL
2328 # won't account for this, so we need to.
2429 window = get_window ()
30+ ctx = window .ctx
2531
2632 pixel_ratio = window .get_pixel_ratio ()
2733 x = int (pixel_ratio * x )
2834 y = int (pixel_ratio * y )
2935
30- a = (gl .GLubyte * 4 )(0 )
31- gl .glReadPixels (x , y , 1 , 1 , gl .GL_RGBA , gl .GL_UNSIGNED_BYTE , a )
32- return tuple (int (i ) for i in a [:components ])
36+ data = ctx .screen .read (viewport = (x , y , 1 , 1 ), components = components )
37+ return tuple (data ) # bytes gets converted to ints in the tuple creation
3338
3439
3540def get_image (
36- x : int = 0 , y : int = 0 , width : Optional [int ] = None , height : Optional [int ] = None
41+ x : int = 0 ,
42+ y : int = 0 ,
43+ width : Optional [int ] = None ,
44+ height : Optional [int ] = None ,
45+ components : int = 4 ,
3746) -> PIL .Image .Image :
3847 """
3948 Get an image from the screen.
4049
4150 Example::
4251
43- image = get_image()
44- image.save('screenshot.png', 'PNG')
52+ # Create and image of the entire screen and save it to a file
53+ image = arcade.get_image()
54+ image.save('screenshot.png')
4555
4656 :param x: Start (left) x location
47- :param y: Start (top ) y location
57+ :param y: Start (bottom ) y location
4858 :param width: Width of image. Leave blank for grabbing the 'rest' of the image
4959 :param height: Height of image. Leave blank for grabbing the 'rest' of the image
50- :returns: A Pillow Image
60+ :param components: Number of components to fetch. By default we fetch 4 (4=RGBA, 3=RGB)
5161 """
5262 window = get_window ()
63+ ctx = window .ctx
64+
65+ if components not in (3 , 4 ):
66+ raise ValueError ("components must be 3 or 4" )
5367
5468 pixel_ratio = window .get_pixel_ratio ()
5569 x = int (pixel_ratio * x )
@@ -63,12 +77,6 @@ def get_image(
6377 width = int (pixel_ratio * width )
6478 height = int (pixel_ratio * height )
6579
66- # Create an image buffer
67- # noinspection PyTypeChecker
68- image_buffer = (gl .GLubyte * (4 * width * height ))(0 )
69-
70- gl .glReadPixels (x , y , width , height , gl .GL_RGBA , gl .GL_UNSIGNED_BYTE , image_buffer )
71- image = PIL .Image .frombytes ("RGBA" , (width , height ), image_buffer )
72- image = PIL .ImageOps .flip (image )
73-
74- return image
80+ data = ctx .screen .read (viewport = (x , y , width , height ), components = components )
81+ image = PIL .Image .frombytes ("RGBA" if components == 4 else "RGB" , (width , height ), data )
82+ return PIL .ImageOps .flip (image )
0 commit comments