Trying to find color value at pixel location

BlitzMax Forums/BlitzMax Beginners Area/Trying to find color value at pixel location

BlitzMan(Posted 2016) [#1]
Graphics 800,600

Global x:Int
Global y:Int
Global r:Int
Global g:Int
Global b:Int

While Not KeyHit (KEY_ESCAPE)

Cls

SetColor 255,0,0
DrawRect 0,0,50,50
SetColor 0,255,0
DrawRect 50,0,50,50

findcolor(10,10,r,g,b)

Printall(r,g,b)

Flip
Wend

'FIND COLOR
Function findcolor(x:Int,y:Int,r:Int,g:Int,b:Int)

GetColor r,g,b

End Function

'PRINT COLOR
Function Printall(r:Int,g:Int,b:Int)

DrawText ("R:" + r,100,100)
DrawText ("G:" + g,100,120)
DrawText ("B:" + b,100,140)

End Function

I am using GetColor probably not a good way of doing it,but this is doing my swede in.

Thanks for any help guys.


Mr. Goober(Posted 2016) [#2]
The GetColor function returns the current drawing color. To get a pixel's color, you will probably need to convert the screen to a pixmap using GrabImage and read the pixel location of the pixmap using ReadPixel. I din't know if there's another way to it.

Keep in mind that when using ReadPixel, it's going to return an integer. The format is likely ARGB or RGBA with 8 bits allocated to each color.


Derron(Posted 2016) [#3]
Instead of GrabImage() you better use GrabPixmap() directly.
Why?

GrabPixmap:TPixmap( x,y,width,height )
vs
GrabImage( image:TImage,x,y,frame=0 )

Means: with GrabImage you grab the whole screen, with GrabPixmap you could adjust params to only grab a small portion (eg. the pixel coordinate you are interested in).



PS: Search function returned this thread telling the same what I suggested.


bye
Ron


grable(Posted 2016) [#4]
Actually, GrabImage uses the dimensions of the image.
GrabPixmap is the faster one though, so long as your not going to draw the image.
If you are going draw it, GrabImage is faster than GrabPixmap+LoadImage.

EDIT: You an draw pixmaps too of course, but that would be slower again. And you get no effects whatsoever.


dw817(Posted 2016) [#5]
Hi BlitzMan:

Likely this is the code you are seeking:
'FIND COLOR
Function findcolor(x:Int,y:Int,r:Int Var,g:Int Var,b:Int Var)
Local pic:TPixmap=GrabPixmap(x,y,1,1),c=ReadPixel(pic,0,0)
r=c Shr 16&$ff ; g=c Shr 8&$ff ; b=c&$ff
EndFunction
To explain it, you are creating a temporary PIXMAP, grabbing a single pixel with it, reading it to C, then breaking out C to the R G B components.

The "var" located in the function arguments specify that these variables will return a value.

I needed something like this myself for an early paint program I was working on.

Hope This Helps !


BlitzMan(Posted 2016) [#6]
Thanks guys

Looks like it is ReadPixel im looking for.:)


dw817(Posted 2016) [#7]
Yep, very surprising that BlitzMAX doesn't have something nice like:

function Pnt(x,y,r,g,b)

likely would cost nothing to implement and likely would be quite a bit faster than my own code above.


Derron(Posted 2016) [#8]
"pnt" is so ... verbose (compared to DrawImage(), ReadPixel() ...).

Maybe the problem is the underlaying "engine" / renderpipeline: BlitzMax just does not know the color of the backbuffer in that moment, it is up to a command to read that information back from the GPU (there everything was "mixed").


bye
Ron


dw817(Posted 2016) [#9]
Well, Derron, GFA wasn't much better. To read a pixel you had to use:
PROCEDURE Pnt(H,V,VAR R,G,B)
  LOCAL C = GetPixel(NewDC(APage|),H,V)
  R = GetRValue(C),G = GetGValue(C),B = GetBValue(C)
RETURN
Where NewDC(APage) was an active virtual page and GetRValue(), GetGValue(), and GetBValue() are functions internal to GFA. I still would like to see virtual pages implemented for BlitzMAX in small and understandable code.
PROCEDURE Xfer(P1,H,V,X,Y,P2,H2,V2,Typ)
  IF Typ = 0 THEN Typ = SRCCOPY
  IF Typ = 1 THEN Typ = SRCAND
  IF Typ = 2 THEN Typ = SRCPAINT
  IF Typ = 3 THEN Typ = SRCINVERT
  BITBLT NewDC(P1),H,V,X,Y,NewDC(P2),H2,V2,Typ
RETURN