@@ -649,12 +649,46 @@ def _set_image_for_button(self, button):
649
649
path_large = path_regular .with_name (
650
650
path_regular .name .replace ('.png' , '_large.png' ))
651
651
size = button .winfo_pixels ('18p' )
652
+
653
+ # Nested functions because ToolbarTk calls _Button.
654
+ def _is_dark (color ):
655
+ # `winfo_rgb` returns an (r, g, b) tuple in the range 0-65535
656
+ return max (button .winfo_rgb (button .cget (color ))) < 65535 / 2
657
+
658
+ def _recolor_icon (image , color ):
659
+ image_data = np .asarray (image ).copy ()
660
+ black_mask = (image_data [..., :3 ] == 0 ).all (axis = - 1 )
661
+ image_data [black_mask , :3 ] = color
662
+ return Image .fromarray (image_data , mode = "RGBA" )
663
+
652
664
# Use the high-resolution (48x48 px) icon if it exists and is needed
653
665
with Image .open (path_large if (size > 24 and path_large .exists ())
654
666
else path_regular ) as im :
655
667
image = ImageTk .PhotoImage (im .resize ((size , size )), master = self )
656
- button .configure (image = image , height = '18p' , width = '18p' )
657
- button ._ntimage = image # Prevent garbage collection.
668
+ button ._ntimage = image
669
+
670
+ # create a version of the icon with the button's text color
671
+ foreground = (255 / 65535 ) * np .array (
672
+ button .winfo_rgb (button .cget ("foreground" )))
673
+ im_alt = _recolor_icon (im , foreground )
674
+ image_alt = ImageTk .PhotoImage (
675
+ im_alt .resize ((size , size )), master = self )
676
+ button ._ntimage_alt = image_alt
677
+
678
+ if _is_dark ("background" ):
679
+ button .configure (image = image_alt )
680
+ else :
681
+ button .configure (image = image )
682
+ if (
683
+ isinstance (button , tk .Checkbutton )
684
+ and button .cget ("selectcolor" ) != ""
685
+ ):
686
+ if _is_dark ("selectcolor" ):
687
+ button .configure (selectimage = image_alt )
688
+ else :
689
+ button .configure (selectimage = image )
690
+
691
+ button .configure (height = '18p' , width = '18p' )
658
692
659
693
def _Button (self , text , image_file , toggle , command ):
660
694
if not toggle :
0 commit comments