Click to See Complete Forum and Search --> : Getting RGB from palette
Paul Warren
Mar 5th, 2001, 05:12 AM
If I have a form which has a background colour of &H00C0C0C0 then it's easy to extract the RGB values. OK, but what if the colour of the form is taken from the current palette so the value is &H0800000F. How do I extract the value 15 from this ? Once I've got that I know how to get the RGB from the API but I'm no maths wizz so any help on getting the 15 from the value would be appreciated.
HarryW
Mar 5th, 2001, 05:47 AM
It just basically means using bitmasks and shifts. Since shifts aren't possible in VB, you have to simulate them with division. This code will get you the red, green and blue parts from a 32-bit colour value:
Red = Colour And 255
Green = Colour \ 256 And 255
Blue = Colour \ 65536 And 255
If you wanted the alpha too, it would be (Colour \ 16777216 And 255).
In case you hadn't noticed:
256 = 2^8
65536 = 2^16
16777216 = 2^24
Paul Warren
Mar 5th, 2001, 05:50 AM
Thanks Harry but I've all ready got the code for splitting out the RGB values. To expand upon my explanation - it's not a question of getting the colour values out, it's all about trying to lose the &H08 from the start of the palette colour number. However, VB looks at the number and thinks it's a negative value ! Help.
HarryW
Mar 5th, 2001, 06:13 AM
Oh... hmm well I've never come across this before since I don't use VB for graphics stuff, but perhaps you could convert it to a string, take off the &H using the Right() function, and then convert it back? A bit messy I know but I don't know how VB is treating the number if it's giving you the &H at the beginning.
I've just realised you said it was sticking &H08 in front of the number... why do you think it shouldn't do that?
Paul Warren
Mar 5th, 2001, 06:40 AM
It should do that, it's how it indicates that the colour is from a palette. You should then remove the 08 from the front and then convert the Hex to get the colour number. I'd come up with checking the hex string and using $ functions but there must be a matchematical approach to this. Thanks for looking at it though - it's really starting to p!ss me off.
HarryW
Mar 5th, 2001, 06:57 AM
Oh, weird.... I guess I'm used to working with C++ with, in this case, more straightforward data. Sorry I couldn't help more :( Maybe Abs() would remove the negativity? Just a last guess.
kedaman
Mar 5th, 2001, 10:16 AM
the thing is that vb uses SIGNED long's that ranges values from -2^31 to 2^31-1, not 0 to 2^32-1. To get around this problem (yeah this been annoying me some time) is to have a currency datatype and add 2^31 if the value is negative. It might also work if you use copymemory with an offset of 2 bytes by copying over the long to a byte array of 8 bytes to 4'th place and then copy it to the currency, then multiply by 10000 to avoid the decimals.
kedaman
Mar 5th, 2001, 10:21 AM
just ignore what i said, you don't need the RGBA, but the components,copy them over to a byte array of 4 instead and you have each component in it's own byte, sorry about the confusion
HarryW
Mar 5th, 2001, 10:21 AM
If you're going to start using CopyMemory, you might as well just copy the 8-bit red, green and blue components straight out of the colour value. Or perhaps I'm missing something that makes it more complicated.
HarryW
Mar 5th, 2001, 10:22 AM
Oh, well looks like you got there just before me :)
kedaman
Mar 5th, 2001, 10:24 AM
a bit slow today? hehe :p
Paul Warren
Mar 6th, 2001, 02:39 AM
Cheers guys. This is what I did in the end :
lTemp = lColor Xor -2147483648#
If lTemp >= 1 Then
lColor = GetSysColor(lTemp)
End If
and that seems to do the trick. Cheers for the help.
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.