@@ -27,24 +27,31 @@ class QRColorMask:
2727 def initialize (self , styledPilImage , image ):
2828 self .paint_color = styledPilImage .paint_color
2929
30- def apply_mask (self , image ):
30+ def apply_mask (self , image , use_cache = False ):
3131 width , height = image .size
32+ pixels = image .load ()
33+ fg_color_cache = {} if use_cache else None
3234 for x in range (width ):
3335 for y in range (height ):
34- norm = self .extrap_color (
35- self .back_color , self .paint_color , image .getpixel ((x , y ))
36- )
36+ current_color = pixels [x , y ]
37+ if current_color == self .back_color :
38+ continue
39+ if use_cache and current_color in fg_color_cache :
40+ pixels [x , y ] = fg_color_cache [current_color ]
41+ continue
42+ norm = self .extrap_color (self .back_color , self .paint_color , current_color )
3743 if norm is not None :
38- image .putpixel (
39- (x , y ),
40- self .interp_color (
41- self .get_bg_pixel (image , x , y ),
42- self .get_fg_pixel (image , x , y ),
43- norm ,
44- ),
44+ new_color = self .interp_color (
45+ self .get_bg_pixel (image , x , y ),
46+ self .get_fg_pixel (image , x , y ),
47+ norm
4548 )
49+ pixels [x , y ] = new_color
50+
51+ if use_cache :
52+ fg_color_cache [current_color ] = new_color
4653 else :
47- image . putpixel (( x , y ), self .get_bg_pixel (image , x , y ) )
54+ pixels [ x , y ] = self .get_bg_pixel (image , x , y )
4855
4956 def get_fg_pixel (self , image , x , y ):
5057 raise NotImplementedError ("QRModuleDrawer.paint_fg_pixel" )
@@ -103,7 +110,7 @@ def apply_mask(self, image):
103110 # the individual pixel comparisons that the base class uses, which
104111 # would be a lot faster. (In fact doing this would probably remove
105112 # the need for the B&W optimization above.)
106- QRColorMask .apply_mask (self , image )
113+ QRColorMask .apply_mask (self , image , use_cache = True )
107114
108115 def get_fg_pixel (self , image , x , y ):
109116 return self .front_color
0 commit comments