@@ -634,6 +634,16 @@ def set_cursor(self, cursor):
634
634
except tkinter .TclError :
635
635
pass
636
636
637
+ def _is_dark (self , button , color ):
638
+ # `winfo_rgb` returns an (r, g, b) tuple in the range from 0 to 65535
639
+ return max (button .winfo_rgb (button .cget (color ))) < 65535 / 2
640
+
641
+ def _recolor_icon (self , image , color ):
642
+ image_data = np .asarray (image ).copy ()
643
+ black_mask = (image_data [..., :3 ] == 0 ).all (axis = - 1 )
644
+ image_data [black_mask , :3 ] = color
645
+ return Image .fromarray (image_data , mode = "RGBA" )
646
+
637
647
def _set_image_for_button (self , button ):
638
648
"""
639
649
Set the image for a button based on its pixel size.
@@ -653,8 +663,30 @@ def _set_image_for_button(self, button):
653
663
with Image .open (path_large if (size > 24 and path_large .exists ())
654
664
else path_regular ) as im :
655
665
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.
666
+ button ._ntimage = image
667
+
668
+ # create a version of the icon with the button's text color
669
+ foreground = (255 / 65535 ) * np .array (
670
+ button .winfo_rgb (button .cget ("foreground" )))
671
+ im_alt = self ._recolor_icon (im , foreground )
672
+ image_alt = ImageTk .PhotoImage (
673
+ im_alt .resize ((size , size )), master = self )
674
+ button ._ntimage_alt = image_alt
675
+
676
+ if (self ._is_dark (button , "background" )):
677
+ button .configure (image = image_alt )
678
+ else :
679
+ button .configure (image = image )
680
+ if (
681
+ isinstance (button , tk .Checkbutton )
682
+ and button .cget ("selectcolor" ) != ""
683
+ ):
684
+ if (self ._is_dark (button , "selectcolor" )):
685
+ button .configure (selectimage = image_alt )
686
+ else :
687
+ button .configure (selectimage = image )
688
+
689
+ button .configure (height = '18p' , width = '18p' )
658
690
659
691
def _Button (self , text , image_file , toggle , command ):
660
692
if not toggle :
0 commit comments