Results 1 to 10 of 10

Thread: How to tell if a color is light or dark?

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2000
    Posts
    299
    I have a problem with letting the user change the backcolor of the form, as the text color is black. Is there a way to check to see if a color is light or dark by its RGB number? If i could do that i could change the text color accordingly?
    Anyone got any ideas on this one? or come across this problem before?
    BW

  2. #2
    Member Visual Programmer's Avatar
    Join Date
    Dec 2000
    Posts
    59
    This isn't what always happens, but if at least 1 RBG number is greater than 200 then its dark, if they are all less then is light.


    Visual Programmer
    VP/Sonic taking on the (vb) world, one post at a time.

  3. #3
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    how about considering color components as base vectors in a 3d coordinate system and have the length of that vector deciding how light it is, like:

    dark=200>sqr(red*red+green*green+blue*blue)
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2000
    Posts
    299

    I think i have made a mistake.

    I am using the ChooseColor API to get the Color Commondialog which returns a long. Thats the number i want to check to see if it was light or dark, or is there an easy way to strip out the RGB number from that? I remember seeing something like this a while ago, but i can't remember where it was.
    I'll look into that first. The number is the number you get when you do
    Msgbox Form1.BackColor
    Thats what i need to split into RGB, then figger out if its light or dark. How about Hex, would it be easier to find out if i had the hex values??
    BW

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2000
    Posts
    299

    Flag that last message

    Well part of it, as i have found the code i had to split the long number into RGB.
    BW

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2000
    Posts
    299

    I don't agree with you.

    Unless the way i'm getting the RGB numbers is different than the way you get them, if a value is larger than 200 then it is going to be lighter.
    I reckon, if R + G + B > 330 then it is light, but if it is less then its dark.
    Just my findings.
    Let me know what you think, i can post the code if needed.
    BW
    ps however having a value of 200+ for G by itself needs to also change from white text to black, as its too bright
    This is the code i ended up using
    Code:
        If (intRed + intGreen + intBlue < 350) And (intGreen < 200) Then
            Label1.ForeColor = vbWhite
        Else
            Label1.ForeColor = vbBlack
        End If
    Last edited by But_Why; Jan 31st, 2001 at 08:32 PM.

  7. #7
    Fanatic Member
    Join Date
    Sep 1999
    Location
    Bethel, North Carolina, USA
    Posts
    987
    I've been wondering about this for some time myself (even though I have no practical use for it) and when I saw this thread I decided to put some research into it and found that you need to determine the luminosity (or brightness as it is also known) for a particular color code. If you want to test to see what I am talking about open MS Paint, goto Options / Edit Colors and play around with the Lum value for any color. The following function returns a value between 0 and 240 where 0 is the darkest and 240 is the lightest a color gets.

    Code:
    Private Sub Form_Load()
     Debug.Print Luminosity(RGB(0, 0, 0))
     Debug.Print Luminosity(RGB(255, 255, 255))
    End Sub
    
    Private Function Luminosity(ByVal pColor As Long) As Integer
     Dim iR As Integer, iG As Integer, iB As Integer
     Dim nRPct As Single, nGPct As Single, nBPct As Single
     Dim nMax As Single, nMin As Single
     Dim nLumPct As Single
     
       'get the individual value for red, green, and blue
       iR = pColor Mod 256
       pColor = pColor \ 256
       iG = pColor Mod 256
       pColor = pColor \ 256
       iB = pColor Mod 256
    
        
       ' get the percentage of each color
        nRPct = iR / 255
        nGPct = iG / 255
        nBPct = iB / 255
        
        ' get highest and lowest percentages
        If nRPct > nGPct And nRPct > nBPct Then
            nMax = nRPct
        ElseIf nGPct > nBPct Then
            nMax = nGPct
        Else
             nMax = nBPct
        End If
            
        If nRPct < nGPct And nRPct < nBPct Then
            nMin = nRPct
        ElseIf nGPct < nBPct Then
            nMin = nGPct
        Else
             nMin = nBPct
        End If
        
        ' get the percentage of luminosity
        nLumPct = (nMin + nMax) / 2
        
        ' return the luminosity min (darkest) = 0 max (lightest) = 240
        Luminosity = nLumPct * 240
        
    End Function
    {Insert random techno-babble here}

    {Insert quote from some long gone mofo here}

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2000
    Posts
    299

    Thats some nice code.

    Works well if you set the condition low enough, eg
    Code:
    if Luminosity(LongRGB) > 100 then 
        DoStuff
    else
        DoOtherStuff
    End if
    But then the code i had works just as well so i'll stick to that for now. It doesn't have to be too accurate, so it works fine, but i'll note down your code too.
    Cheers.
    BW
    Last edited by But_Why; Feb 1st, 2001 at 02:53 PM.

  9. #9
    Guest
    you should go with the middle of the RGB value. 0-127 = dark, 128+ = light.

  10. #10
    Frenzied Member
    Join Date
    Jul 1999
    Location
    Huntingdon Valley, PA 19006
    Posts
    1,151

    I used this function & experimented.

    Ihad the same problem in an application for which the user was allowed to fiddle with background colors in a text box. I used the following function to obtain an average color value.
    Code:
    Public Function ColorIntensity(ColorValue As Long) _
                                            As Integer
    Dim J As Integer
    Dim X(1 To 4) As Integer
    Dim TotalIntensity As Integer
    Dim HexString As String
    Dim HexNumber As Long
    
    HexNumber = ColorValue
    
    For J = 1 To 4
        X(J) = HexNumber Mod 256
        HexNumber = (HexNumber - X(J)) / 256
        
      Next J
    
    TotalIntensity = X(1) + X(2) + X(3)
    
    ColorIntensity = TotalIntensity / 3
    
    End Function
    I experiemented a bit and used the following in the main line.
    Code:
    If ColorIntensity(BackGroundColor) < 85 _
                Or BackGroundColor = vbBlue Then
            txtBname(TextSlot).ForeColor = vbYellow
        Else
            txtBname(TextSlot).ForeColor = vbBlack
      End If
    You might find that some other average value suits your fancy. A lot of my users chose vbBlue, on which black type was hard to read. Otherwise, my cutoff of 85 worked okay.

    BTW: The For loop could be 1 to 3 instead of 1 to 4. It worked, so I never fixed it.
    Live long & prosper.

    The Dinosaur from prehistoric era prior to computers.

    Eschew obfuscation!
    If a billion people believe a foolish idea, it is still a foolish idea!
    VB.net 2010 Express
    64Bit & 32Bit Windows 7 & Windows XP. I run 4 operating systems on a single PC.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width