We help IT Professionals succeed at work.

Calculating 'brightness' of a bitmap

Medium Priority
Last Modified: 2013-11-19
I am trying to create a self-adjusting brightness feature for a videophone.  I can take a 'snapshot' of the video in .bmp format.  I need to  somehow measure the brightness of that bitmap.  Open to any ideas.  Here is how I plan to do it:
1.  convert the bitmap to grayscale.
2.  Average the grayscale for each pixel, giving me an average "grayness" for the whole bitmap.

Q:  How do I convert the bitmap to grayscale?
    How do I access the individual bits of a bitmap.

BTW, I'm using VB 5.0 Enterprise Edition.

Watch Question

First, converting R(ed)G(reen)B(lue) values to grayscale:

Gray = 0.3*Red + 0.59*Green + 0.11*Blue

Averaging these gives you one estimate of "brightness"

For getting these RGB values, use GetPixel API function

Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

From this extract individual RGB values. If you want example code, let me know.

For any bigger BMP this will be quite slow process, so my suggestion is that you randomly sample the BMP and evaluate the average brigthness from those values. You can even weigh certain areas of your picture if necessary.

Hope this gets you started.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts


Rantanen- Looks very useful.  Yes, sample code would be much appreciated, specifically how the RGB values are stored in the return (long) from GetPixelLib().  If its its too long to post on the 'xchange, you can email it to 'nichols@teleport.com'
Clay -
  Note that the GetPixel function will just be reading the screen and not the actual values of the bitmap.  
  If the user has their color depth set to 16 colors, you are going to get incorrect results.  You also have be carefull of 256 color modes, where palette flash can corrupt the bitmap colors.

  You'd probably want to open the BitMap as a binary file, and read what the bitmap actually is storing for it's pixels.  Then use rantanen's Greyscale conversion (great code... didn't know it was so simple!)



he's talking about videophone and I understand he wants to adjust what is seen on the screen, If we were talking about manipulating "still pictures" - yes, I agree with you.

Palette flash is a fact of life, but anyway the control must be quite heavily damped (=slow) in this case, so I wouldn't be too concerned about this. There are many more fast disturbances possible in this kind of application which must be damped away - like somebody lighting a cigarette just in front of the camera. Luckily they are banning smoking in more and more places, so this also is not so big problem :-)

sorry - the last comment I made was addressed to Chris.
Clay & Rantanen -

  What I was refering to was nothing to do with Videophone or still images.  What I'm refering to is what Windows does when you try to display a 24 bit color image on a system that is set up for 16 bit, 8 bit or 4 bit.  Windows uses a system palette, which is totaly different from the bitmap/GIF/JPEG palette.

  What happens is best described with 256 color systems.  If your bitmap is a 24 bit color (8 bits RGB), the bitmap can contain up to 16.7 million different colors, each pixel being described by three numbers from 0 to 255, one in each primary color (red, green, & blue).  In a 256 color system, Windows can only display 256 colors at a time.  When it loads the bitmap, if the color is in it's current system palette of 256 colors, it displays the pixel normally.  If it's not in the current system palette, it picks a color that is close to the color in the bitmap.  This will result in some of the pixels that are being displayed not having the same color value as is stored in the bitmap.

  Easy way to see this is to change your display to either 16 colors or 256 colors, then load a 24 bit color bitmap in Paint, and look at it.  It will appear slightly different from what it appears when your monitor is set to 24 bit (true color).  To see "palette flash", set your display to 256 colors, and open two instances of paint.  Load two different images (pick ones with different colors :) and make each one active.  As a different Paint becomes active, Windows will change the current palette to one that better fits the active window.  

  Now, as to how to deal with this for your problem.  I would open the Bitmap that you are using as a binary file, and read each pixel that way.  By doing so, you get a representation of what is in the bitmap, not what Windows is displaying.  

Hope this clears things up,



what you say is true when you are writing e.g. a photo manipulation program, but in my opinion it is not relevant in this situation.

I don't think Clay is trying to manipulate the bitmaps on the fly with VB (!!!), he's trying to control the hardware and that is totally different thing.

If I'm wrong when doing this assumption my advice to Clay would be forget VB. But ifmy assumption is correct, then even these 16 or 256 color pictures shown on screen react to lighting condition changes and these can be adjusted changing hardware settings (I don't know the technology here to be more specific). 16 color pictures react less, 256 color pictures somewhat more and so on.

That is how I have understood this question here,.


My interest is in the colors actually displayed on the screen.  The video is 256 colors (8-bit) and the PC is set for at least 16-bit color.  That avoids palette flash.  (We have only one other application on the screen and its only got 256-colors).

I haven't been able to find out how to decode the long value returned, into R G B colors.  Any ideas?

maybe the source I sent to you was not clear enough because I had tried to optimize it a little bit.

To find out R,G and B components from the long value returned by GetPixel do

        nRed = nRed + Int(nRGB / &H10000 And &HFF)
        nGreen = nGreen + Int(nRGB / &H100 And &HFF)
        nBlue = nBlue + Int(nRGB And &HFF)



Thanks for the detail.  One question:
With nRed = nRed + Int(nRGB / &H10000 And &HFF)
Where does   ^^^ get defined?  Or is this a cummulative count you are keeping (summing the red in all the pixels?  I.e. are you keeping a running total here?

BTW, the only source code I got was what you posted to the 'exchange here, unless you emailed it to me at work (nichols@murphysw.com).  I'll check there tomorrow.


oops - yes it was a code snippet from the sub below and as you said, a cumulative count.

Private Function GetBrightness(picX As PictureBox, nSamples As Integer, nX As Integer, nY As Integer) As Single
    Dim I As Integer
    Dim nRGB As Long
    Dim nRed As Integer
    Dim nGreen As Integer
    Dim nBlue As Integer
    Dim nGray As Integer
    Dim nRedSum As Long
    Dim nGreenSum As Long
    Dim nBlueSum As Long
    Dim nSum As Long
    For I = 1 To nSamples
        nRGB = GetPixel(picX.hdc, Int(Rnd() * nX), Int(Rnd() * nY))
        nRedSum = nRedSum + Int(nRGB / &H10000 And &HFF)
        nGreenSum = nGreenSum + Int(nRGB / &H100 And &HFF)
        nBlueSum = nBlueSum + Int(nRGB And &HFF)
    Next I
    nSum = (0.3 * nRedSum + 0.59 * nGreenSum + 0.11 * nBlueSum) / nSamples
    GetBrightness = 100 * nSum / 255
End Function

I posted my sample to  'nichols@teleport.com'  which address you gave in an earlier note.

My address is 'Lasse.Rantanen@sci.fi'


Opps.  Gave you the wrong address.  its cnichols@teleport.com, note the 'c'.
Thanks for all the help!


Please resubmit any answer so I can credit you with the answer.  Sorry I didn't get back to this sooner.
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.