1111from PIL import Image
1212import PIL
1313import upcean
14+ import ctypes
1415
1516# Constants
1617NUM_BARCODES = 12
3536
3637# Barcode and Position Initialization Functions
3738def create_barcode ():
38- barcode = upcean .oopfuncs .barcode ()
39- barcode_type = random .choice (["upca" , "upce" , "ean13" , "ean8" , "itf14" ])
40- barcode .type = barcode_type
41-
42- # Assign code based on type
43- code_length = {"upca" : 11 , "upce" : 7 , "ean13" : 12 , "ean8" : 7 , "itf14" : 13 }[barcode_type ]
44- barcode .code = str (random .randint (0 , 10 ** code_length - 1 )).zfill (code_length )
39+ while (True ):
40+ barcode = upcean .oopfuncs .barcode ()
41+ barcode_type = random .choice (["upca" , "upce" , "ean13" , "ean8" , "itf14" ])
42+ barcode .type = barcode_type
43+ # Assign code based on type
44+ code_length = {"upca" : 11 , "upce" : 7 , "ean13" : 12 , "ean8" : 7 , "itf14" : 13 }[barcode_type ]
45+ barcode .code = str (random .randint (0 , 10 ** code_length - 1 )).zfill (code_length )
46+ if (barcode .validate_checksum ()):
47+ break ;
4548 barcode .code = barcode .fix_checksum ()
4649 return barcode
4750
4851def generate_barcode_image (barcode ):
4952 barcode .size = BARCODE_SIZE
50- barcode_img = barcode .validate_draw_barcode ().convert ("RGBA" )
53+ barcode_img = barcode .validate_draw_barcode ()[ 1 ] .convert ("RGBA" )
5154 barcode_img = barcode_img .rotate (random .randint (0 , 360 ), Image .BICUBIC , True )
5255 return barcode_img
5356
54- def convert_pillow_to_sdl2_surface (image ):
55- """Converts a Pillow Image to an SDL2 Surface"""
56- image_data = image .tobytes ()
57+ def pillow_to_sdl_texture (renderer : sdl2 .ext .Renderer , pil_img ):
58+ img = pil_img .convert ("RGBA" )
59+ w , h = img .size
60+ pitch = w * 4
61+
62+ buf = ctypes .create_string_buffer (img .tobytes ())
5763 surface = sdl2 .SDL_CreateRGBSurfaceWithFormatFrom (
58- image_data , image .width , image .height , 32 , image .width * 4 , sdl2 .SDL_PIXELFORMAT_RGBA32 )
59- return surface
64+ buf , w , h , 32 , pitch , sdl2 .SDL_PIXELFORMAT_RGBA32
65+ )
66+ if not surface :
67+ raise RuntimeError (sdl2 .SDL_GetError ().decode ())
68+
69+ # NOTE: Texture wants (renderer, surface)
70+ tex = sdl2 .ext .Texture (renderer , surface )
71+
72+ sdl2 .SDL_FreeSurface (surface )
73+ return tex
6074
6175def random_position ():
6276 return [random .randint (0 , WIDTH ), random .randint (0 , HEIGHT )]
6377
78+ # Renderer
79+ renderer = sdl2 .ext .Renderer (window )
80+ running = True
81+
6482# Initialize Barcodes, Images, Positions, and Directions
6583barcodes = [create_barcode () for _ in range (NUM_BARCODES )]
6684barcode_images = [generate_barcode_image (barcode ) for barcode in barcodes ]
67- sdl_surfaces = [convert_pillow_to_sdl2_surface ( image ) for image in barcode_images ]
85+ sdl_textures = [pillow_to_sdl_texture ( renderer , image ) for image in barcode_images ]
6886positions = [random_position () for _ in range (NUM_BARCODES )]
6987directions = [(random .choice ([- 2 , - 1 , 1 , 2 ]), random .choice ([- 2 , - 1 , 1 , 2 ])) for _ in range (NUM_BARCODES )]
7088
71- # Renderer
72- renderer = sdl2 .ext .Renderer (window )
73- running = True
74-
7589# Animation Loop
7690while running :
7791 renderer .clear (0 ) # Clear with black background
@@ -90,11 +104,11 @@ def random_position():
90104 directions [i ] = (random .choice ([- 2 , - 1 , 1 , 2 ]), random .choice ([- 2 , - 1 , 1 , 2 ]))
91105 barcodes [i ] = create_barcode ()
92106 barcode_images [i ] = generate_barcode_image (barcodes [i ])
93- sdl_surfaces [i ] = convert_pillow_to_sdl2_surface ( barcode_images [i ])
107+ sdl_textures [i ] = pillow_to_sdl_texture ( renderer , barcode_images [i ])
94108
95109 # Convert position and draw on screen
96110 dst_rect = sdl2 .SDL_Rect (pos [0 ], pos [1 ], barcode_images [i ].width , barcode_images [i ].height )
97- renderer .copy (sdl_surfaces [i ], None , dst_rect )
111+ renderer .copy (sdl_textures [i ], None , dst_rect )
98112
99113 # Present the renderer
100114 renderer .present ()
@@ -109,7 +123,4 @@ def random_position():
109123 if event .key .keysym .sym in {sdl2 .SDLK_ESCAPE , sdl2 .SDLK_q }:
110124 running = False
111125
112- # Clean up and quit
113- for surface in sdl_surfaces :
114- sdl2 .SDL_FreeSurface (surface )
115126sdl2 .ext .quit ()
0 commit comments