Android Tutorial Getting the Contrast Color (for a label, etc)

eelias

Active Member
Licensed User
There are situations where we change the panel colors, like when the user select its own color, and we dont know if the text of the labels will be seen. Commonly we define black or white for text color according to the background color.

The code below can be used for that:

B4X:
' decopose Color value to ARGB values
Sub GetARGB(Color As Int) As Int()
    Dim res(4) As Int
    res(0) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff000000), 24)
    res(1) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff0000), 16)
    res(2) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff00), 8)
    res(3) = Bit.AND(Color, 0xff)
    Return res
End Sub

' Return the High Contract color (black or white) according to the selected color for background
Sub ContrastColor(C As Int) As Int
            Dim d As Int
         Dim a As Double
          Dim argb() As Int
          argb = GetARGB(C)
   
             a = 1 - ( 0.299 * argb(1) + 0.587 * argb(2) + 0.114 * argb(3))/255

            If a < 0.5 Then
                d = 0 ' bright Colors - black font
            Else
                d = 255 ' dark Colors - white font
         End If

            Return  Colors.RGB(d, d, d)
End Sub
as an example:

B4X:
Sub Activity_Create(FirstTime As Boolean)
   Dim pan As Panel
   pan.Initialize
   pan.Color = Colors.Blue
   
   Dim lbl As Label
   lbl.Initialize
   lbl.TextColor = ContrastColor(pan.Color)
   lbl.Text = "you will aways see me"
   
   pan.AddView(lbl, 1, 1, 200dip, 30dip)
   Activity.AddView(pan, 0, 0, 100%x, 100%y)
end sub
In this example you can change pan.color to any desired color and the text will be always in a high contrast, based on the panels color. It will show up black or white.

The ContrastColor makes an adjustment considering that the green color is better perceived.

have fun.

EDIT: Corrected an error on the function thanks to klaus!

Eduardo
 
Last edited:

klaus

Expert
Licensed User
Are you sure that this line
B4X:
a = 1 - ( 0.299 * argb(1) + 0.587 * argb(2) + 0.114 * argb(2))/255
shouldn't be
B4X:
a = 1 - ( 0.299 * argb(1) + 0.587 * argb(2) + 0.114 * argb(3))/255
You find the source of the equation here.

Best regards.
 
Last edited:

eelias

Active Member
Licensed User
Are you sure that this line
B4X:
a = 1 - ( 0.299 * argb(1) + 0.587 * argb(2) + 0.114 * argb(2))/255
shouldn't be
B4X:
a = 1 - ( 0.299 * argb(1) + 0.587 * argb(2) + 0.114 * argb(3))/255
You find the source of the equation here.

Best regards.
Klaus, Yes! you right, I typed wrong, I have already edited and corrected the post with the propert index. I got the equation from other place, but it is the same you pointed and works very well.

Regards.
 

metrick

Active Member
Licensed User
There are situations where we change the panel colors, like when the user select its own color, and we dont know if the text of the labels will be seen. Commonly we define black or white for text color according to the background color.

The code below can be used for that:

B4X:
' decopose Color value to ARGB values
Sub GetARGB(Color As Int) As Int()
    Dim res(4) As Int
    res(0) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff000000), 24)
    res(1) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff0000), 16)
    res(2) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff00), 8)
    res(3) = Bit.AND(Color, 0xff)
    Return res
End Sub

' Return the High Contract color (black or white) according to the selected color for background
Sub ContrastColor(C As Int) As Int
            Dim d As Int
         Dim a As Double
          Dim argb() As Int
          argb = GetARGB(C)
  
             a = 1 - ( 0.299 * argb(1) + 0.587 * argb(2) + 0.114 * argb(3))/255

            If a < 0.5 Then
                d = 0 ' bright Colors - black font
            Else
                d = 255 ' dark Colors - white font
         End If

            Return  Colors.RGB(d, d, d)
End Sub
as an example:

B4X:
Sub Activity_Create(FirstTime As Boolean)
   Dim pan As Panel
   pan.Initialize
   pan.Color = Colors.Blue
  
   Dim lbl As Label
   lbl.Initialize
   lbl.TextColor = ContrastColor(pan.Color)
   lbl.Text = "you will aways see me"
  
   pan.AddView(lbl, 1, 1, 200dip, 30dip)
   Activity.AddView(pan, 0, 0, 100%x, 100%y)
end sub
In this example you can change pan.color to any desired color and the text will be always in a high contrast, based on the panels color. It will show up black or white.

The ContrastColor makes an adjustment considering that the green color is better perceived.

have fun.

EDIT: Corrected an error on the function thanks to klaus!

Eduardo
I got compiling error. "Color is writeonly." when compiling above codes.
 

JohnD

Active Member
Licensed User
I got the same error as metrick above. I changed the calling code in Activity_Create and got it to work. Change the 2 occurrences of Colors.Green to whatever you want to play around with it.

B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.Initialize(0)
   
    Dim pan As Panel
    pan.Initialize(0)
    pan.Color = Colors.Green
 
    Dim lbl As Label
    lbl.Initialize(0)
    lbl.TextColor = ContrastColor(Colors.Green) 
    lbl.Text = "you will aways see me"
 
    pan.AddView(lbl, 1, 1, 200dip, 30dip)
    Activity.AddView(pan, 0, 0, 100%x, 100%y)
End Sub
 
Top