Calculating 'brightness' of a bitmap

Posted on 1997-11-03
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.

Question by:clay111296
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
  • 2

Accepted Solution

rantanen earned 200 total points
ID: 1439615
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.

Author Comment

ID: 1439616
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 ''

Expert Comment

ID: 1439617
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!)

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 1439618

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 :-)

Expert Comment

ID: 1439619
sorry - the last comment I made was addressed to Chris.

Expert Comment

ID: 1439620
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,


Expert Comment

ID: 1439621

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,.

Author Comment

ID: 1439622
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?

Expert Comment

ID: 1439623
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)


Author Comment

ID: 1439624
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 (  I'll check there tomorrow.


Expert Comment

ID: 1439625

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  ''  which address you gave in an earlier note.

My address is ''

Author Comment

ID: 1439626
Opps.  Gave you the wrong address.  its, note the 'c'.
Thanks for all the help!

Author Comment

ID: 1439627
Please resubmit any answer so I can credit you with the answer.  Sorry I didn't get back to this sooner.

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question ( in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
In this Micro Tutorial viewers will learn the basic shortcuts and functions of Illustrator. The viewer will learn about the paintbrush tool, anchor points, font sizing, and more.
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…
Suggested Courses

630 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question