How to get color from bitmap? (C++)

h4ever

Member
Aug 30, 2013
163
0
0
Hi,
It is from MSDN example of locking bitmap, where this code is shown. They read pixels and detects the color or set it. However I dont understand why the color is only simple value like 0-255. I would expect RGB with three values : Red, Green, Blue. So it is not clear to me how can I get the value which I looks for. For example I would want to look for color in hex color="aaff08" ... So how should I convert it and which function to use to get the correct value in RGB. It contains no alpha channel. (I am beginner in C++)


http://paste.ofcode.org/ntpebmjHEBYWdvzeX4H25p
line 39-40

Code:
for ( int counter = 8; counter < rgbValues->Length; counter += 9 )
rgbValues[ counter ] = 255;
This is the code they use, and here the rgbValues with single integer is quite strange to me.
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
A single integer is four bytes, so it is large enough to hold the r, g, b, and alpha channels. As to why they are setting it to 255, I am not sure. It could be they want a single color, so writing one byte to an integer should result in... blue I think.
 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
It is the datatype. They are copying the values into a byte array. Bytes store the values of 0->255 .

In the MS example (I'm guessing you are referring to this one) They shift by 3 bytes at a time, one byte for each color. In memory, the layout would look like this.

BGRBGRBGRBGRBGR (windows is backwards from the rest of the world).

So the index into this array would look something like this

Code:
 B   G   R   B   G   R ...
 ^   ^   ^   ^   ^   ^ ...
[0] [1] [2] [3] [4] [5]...
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
> // Set every ninth value to 255.
> for ( int counter = 8; counter < rgbValues->Length; counter += 9 )

They are leaving most bytes 0, so the color is ( 0, 0, 255) or b=0, g=0, r=ff

For a different color you would do something like this (C++)
Code:
int r, g, b;
r = 128; g = 128; b = 255;
for ( int counter = 0; counter < rgbValues->Length; counter += 3 ) // 3 NOT 9
 [ counter  +0 ] = b ;
 [ counter  +1 ] = g ;
 [ counter  +2 ] = r ;
 

h4ever

Member
Aug 30, 2013
163
0
0
It is the datatype. They are copying the values into a byte array. Bytes store the values of 0->255 .

In the MS example (I'm guessing you are referring to this one) They shift by 3 bytes at a time, one byte for each color. In memory, the layout would look like this.

Oh yes, you're right. I have changed the code a bit, so it produces different color than in the MSDN example. Thanks for your explanation. Should the upper limit for the loop be image_width*image_height*3 ? As I noticed, in the example there is rgbValues->Length equal to (pImage->Width*pImage->Height). That's also strange to me.

e8re4y.jpg


As a result in my image 800*600 the rgbValues lentgh is 1920000

Edit
Well - one more test I did. I set the width of locked area of bitmap to 5, however the stride is still 3200. So I thought that if I change the with to 5 the stride should be 5. MSDN says "The stride is the width of a single row of pixels (a scan line), rounded up to a four-byte boundary. " So the stride is 4 byte meaning is holds alpha, green, blue and red component, every one byte. However when the bitmap is locked to width 5 so why stride is not 5*4=20 ?
 
Last edited:

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
No, the total length for the entire row is rounded up to a total length that is a multiple of 4. Each pixel size is not rounded up from 3 to 4.

So 5 pixels = 5 * 3 (r,g,b) = 15, rounded up to a multiple of 4 = 16.

row length = x pixels * 3 ; // 24 bit image
while (row length % 4) != 0
row length ++ ;