getting the rgb variables from getcolor

BlitzMax Forums/BlitzMax Beginners Area/getting the rgb variables from getcolor

AvestheFox(Posted 2010) [#1]
Okay, so in regular blitz3D you can get the rgb variables like so:

red=colorred()
green=colorgreen()
blue=colorblue()

these functions dont seem to exist in Blitzmax

so what can I do as a substitute?


rs22(Posted 2010) [#2]
Local r:Int
Local g:Int
Local b:Int

GetColor(r, g, b)
GetColor() puts the values into variables.


AvestheFox(Posted 2010) [#3]
rs22: that was fast xD you answered even though my post wasnt even finished and I hit the wrong button :P


AvestheFox(Posted 2010) [#4]
but what I want to do is read the colors back into a variable like so:

blitz3D code:



AvestheFox(Posted 2010) [#5]
Or in other words, I'd like to get the rgb values of an an exact x and y coordinate and return the numbers to three separate variables one for red, one for green and one for blue

I'm having a hard time trying to figure this out

my post above shows how easy it is in just simple Blitz3D


Jesse(Posted 2010) [#6]
you can't grab colors of the back buffer you have to grabPixmap or grabImage from the back buffer then read pixels from the pixmap(image has a pixmap also).


TomToad(Posted 2010) [#7]
Depends on what you are reading the pixel from. If, like Jesse says, you are trying to get it from the backbuffer, then you need to use GrabPixmap() first. If from a TIMage, then you need to use LockImage() first. After that, you now have a pixmap to read from.
Once you get the pixmap, and the x/y coordinates of the pixel you want to read, you use
Local Color:int = ReadPixel(Pixmap,x,y)
This reads in the pixel in ARGB format. To get Red, Green , and Blue components, you need to extract the information like so.

Local Red:int = (Color Shr 16) & $FF
Local Green:int = (Color Shr 8) & $FF
Local Blue:Int = Color & $FF

It's a lot for something so simple in Blitz3D. I believe it was done this way for performance. I do believe that in the code archives is a function which does the extraction for you.

Edit: There's a few different versions here
http://www.blitzbasic.com/codearcs/codearcs.php?code=2236


AvestheFox(Posted 2010) [#8]
so if I were to read the rgb data from the pixels of a set of tiles (to later be read into a pixel image editor made up of colored 8x8 tiles) in theory I could do something like this?



and what does the '& $FF' bits in the code mean?

I'll be looking at that tutorial too.. but right now I'm trying to understand a bit of the basics :P


Jesse(Posted 2010) [#9]

so if I were to read the rgb data from the pixels of a set of tiles (to later be read into a pixel image editor made up of colored 8x8 tiles) in theory I could do something like this?


you can but you are doing to extra work. you don't need to store the colors for each pixel in a type when they are stored compressed in the pixmap.
you can actually copy pixmap data like this:
color = readpixle(pixmap1:Tpixmap,x,y)
writpixel(pixmap2:Tpixmap,x,y,color)

In hex values each two letters represent a value for for a color:
AARRGGBB = $1FC2DDCC:

AA=$1F - ALPHA
RR=$C2 - RED
GG=$DD - GREEN
BB=$CC - BLUE

and $ff is the hexadecimal value for 255.
you can actually substitute 255 for $FF.
if you want to know what any hexadecimal value represent
you can print it:
print $FF

the reason its done like that is because it's easier on the eyes and mind once you understand it.
you can also print binary value of a number:
print bin($1FC2DDCC)

That color sequence is valid for PC(little Endian) not PPC Mac(Big Endian).
intel mac? I don't know.


TomToad(Posted 2010) [#10]
& is bitwise AND. It takes two bits and sets the output bit only if both input bits are set. It's kind of like And when used with if..Then statements. And is True when both expressions are true.
    |-Both bits set - C is set
    ||-Only A Set - C is not set
    |||-Only B Set - C is not set
    ||||-neither A nor B set - C is not set
    vvvv
A = 1100
B = 1010
-----------
C = 1000

Doing something like & $FF is what is referred to as masking. Basically, you are setting to 0 the bits you are not interested in, while leaving all other bits the same. $FF is hexidecimal notation for binary %11111111.
Notice that is 8 bits, so basically you are masking the lower 8 bits while setting all the rest to 0.

Now the ReadPixel() command returns a 32 bit number with all the color components packed inside like so:
3322222222221111111111
10987654321098765432109876543210
AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB

Doing Color & $FF will mask the lower 8 bits, leaving only the Blue component.

Color = 11111111101010101100110001110111 <- Returned by ReadPixel()
Mask  = 00000000000000000000000011111111 <- & $FF
--------------------------------------------------------------
Blue  = 00000000000000000000000001110111 <- Only blue component left

To get the Green component, you need to mask the green bits. However, doing Color & $FF00 won't work. it is true that it'll leave only the green component, but it will be Green * 256. By doing Shr 8 first, will shift the Color right 8 bits, leaving the green component where the blue was. You can also do (Color & $FF00) Shr 8, that would work, down to preference.

Hopefully I made that clear. Probably not. :)

Also, like Jesse said, you don't need to extract the individual components unless you need to do something with the specific color. For example, if you are writing a function to rotate a pixmap 90 degrees, there is no need to know the individual components. Just copy the pixel as returned by ReadPixel()


Jesse(Posted 2010) [#11]
@TomToad
I am glad I didn't explained that. I would have made a mess, no way as elegant as your explanation. Even with your explanation which I think is really good, I think some newbie guys will find it hard to understand.


AvestheFox(Posted 2010) [#12]
@TomToad and Jesse: your explanations were well understood. Much thanks!

The reason why I am calling the rgb values into separate variables is not to copy pixel elements to other pixels. Its so I can match those variables with other variables that would tell the colored tilesets which color tile needs to be shown for that tile...

Its a bit complicated to explain so here's a link to another thread in the Blitz3D forums where I was doing this before:

http://www.blitzbasic.com/Community/posts.php?topic=91215

needless to say, I believe Tom's explanation is what I needed to do this in BLitzMax :) thanks!


TomToad(Posted 2010) [#13]
Yeah, the problem with the fact ReadPixel() returns a single int and SetColor() expects 3 bytes.
Of course, you could avoid the whole problem altogether by using a scaled TImage with smoothing turned off.



AvestheFox(Posted 2010) [#14]
true.. but the purpose of the editor is to take each pixel of the finished image and turn them into data like this:



that's an 8 x 8 image map (though I'm aiming for a 16 x 16 image, but this will do for a good example)

I'm sure there's a way to do this with just a regular image, and it probably would be easier... I'll just have to look more into it :P


Jesse(Posted 2010) [#15]
you can also still keep it as integer and make a function like this:
Function changeColor(color:Int)
	SetColor (color Shr 16) & $ff,(color Shr 8)& $ff,color & $ff
End Function



AvestheFox(Posted 2010) [#16]
@Jesse: that would certainly work for that purpose

cool idea! :)