Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Calculating 'brightness' of a bitmap

Posted on 1997-11-03
13
Medium Priority
?
1,113 Views
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.

TIA
0
Comment
Question by:clay111296
[X]
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
13 Comments
 
LVL 4

Accepted Solution

by:
rantanen earned 800 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.
0
 

Author Comment

by:clay111296
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 'nichols@teleport.com'
0
 
LVL 3

Expert Comment

by:ChrisLewis
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!)

Chris
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 4

Expert Comment

by:rantanen
ID: 1439618
clay,

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 :-)
0
 
LVL 4

Expert Comment

by:rantanen
ID: 1439619
Clay,
sorry - the last comment I made was addressed to Chris.
0
 
LVL 3

Expert Comment

by:ChrisLewis
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,

Chris
0
 
LVL 4

Expert Comment

by:rantanen
ID: 1439621
Chris,

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

Author Comment

by:clay111296
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?
0
 
LVL 4

Expert Comment

by:rantanen
ID: 1439623
Clay,
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)

HTH
0
 

Author Comment

by:clay111296
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 (nichols@murphysw.com).  I'll check there tomorrow.

0
 
LVL 4

Expert Comment

by:rantanen
ID: 1439625
Clay,

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'
0
 

Author Comment

by:clay111296
ID: 1439626
Opps.  Gave you the wrong address.  its cnichols@teleport.com, note the 'c'.
Thanks for all the help!
0
 

Author Comment

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

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
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.
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Suggested Courses

715 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