ReadPixels (Mojo2) returns only background color.
Monkey Forums/Monkey Programming/ReadPixels (Mojo2) returns only background color.
| ||
Hail, I am new on Monkey X, and i am trying use it in a project of mine. When using ReadPixels to get data from canvas I'm having an issue. I can't get data from color drawn but only the background color. Can anyone help me? |
| ||
it would help if you could post the source code so we could know what you are doing wrong. |
| ||
Sorry. =)Strict Import mojo2 Import brl.filestream Function Main:Int() New Game() Return 0 End Class Game Extends App Field canvas:Canvas Field scrW:Int = 320 Field scrH:Int = 240 Method OnCreate:Int() SetDeviceWindow(scrW, scrH, 4) SetUpdateRate(60) canvas = New Canvas() canvas.SetProjection2d(0, scrW, 0, scrH) Return 0 End Method OnRender:Int() Local pixscan:DataBuffer = New DataBuffer((20 * 20) *4) Local colors:Int[] Local rgba:Int[] rgba = rgba.Resize((20 * 20) *4) colors = colors.Resize(20 * 20) canvas.Clear() canvas.SetColor(1, 0, 0) canvas.DrawPoint(1, 0) canvas.SetColor(0, 1, 0) canvas.DrawPoint(2, 0) canvas.SetColor(0, 0, 1) canvas.DrawPoint(3, 0) canvas.Flush() canvas.ReadPixels(0, 0, 20, 20, pixscan) pixscan.PeekBytes(0, rgba) 'Return: [0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, ...] pixscan.PeekInts(0, colors) 'Return: [-16777216, -16777216, -16777216, -16777216, ...] Return 0 End End Doesn't matter if I put the ReadPixels before or after the Canvas Flush. |
| ||
Hi Clecius, I have been trying to figure out how to implement how to read pixels from the screen but for some reason it's not working right, either I don't understand it or it's not working correct, I did some pixel reading. and it appears as if it doesn't read the alpha from the screen and it gets replaced with 0 which makes it invisible when trying to paste it to an image. And even after modifying the pixels to a visible alpha, it doesn't draw it in the correct color. So i don't know what to tell you. if no one else is able to help, Email BRL(Mark) and see what he tells you. this is the code I was testing it with: Strict Import mojo2 Import brl Function Main:Int() New Game() Return 0 End Class Game Extends App Field canvas:Canvas Field scrW:Int = 320 Field scrH:Int = 240 Field image:Image Field icanvas:Canvas Field pixscan:DataBuffer Field colors:Int[] Field rgba:Int[] Field color:String Method OnCreate:Int() SetDeviceWindow(scrW, scrH, 4) pixscan = New DataBuffer((3*1) *4) SetUpdateRate(5) canvas = New Canvas() image = New Image(50,50) icanvas = New Canvas(image) icanvas.Clear(0,0,0) ' canvas.SetProjection2d(0, scrW, 0, scrH) canvas.Clear(0,0,0) canvas.SetColor(1.0, 0.0,0.0,255.0) canvas.DrawPoint(3, 3) 'canvas.SetColor(0, 1, 0) canvas.DrawPoint(4, 3) 'canvas.SetColor(0, 0, 1) canvas.DrawPoint(5, 3) colors = colors.Resize(3 * 1) canvas.SetColor(0,0,0,0) canvas.ReadPixels(3, 3, 3,1, pixscan) Local i:Int = pixscan.PeekInt(0) ' pixscan.PokeInt(0,i | $FF) i = pixscan.PeekInt(0) Print ((i Shr 24) & $FF)+"'"+((i Shr 16) & $FF)+","+((i Shr 8) & $FF)+","+(i & $FF) i = pixscan.PeekInt(1) 'pixscan.PokeInt(1,i | $FF) i = pixscan.PeekInt(1) Print ((i Shr 24) & $FF)+","+((i Shr 16) & $FF)+","+((i Shr 8) & $FF)+","+(i & $FF) i = pixscan.PeekInt(2) 'pixscan.PokeInt(2,i | $FF) i = pixscan.PeekInt(2) Print ((i Shr 24) & $FF)+","+((i Shr 16) & $FF)+","+((i Shr 8) & $FF)+","+(i & $FF) image.WritePixels(10,10,3,1,pixscan) canvas.SetColor(1,1,1,1) canvas.DrawImage(image,150,150) canvas.Flush() Return 0 End Method OnRender:Int() Return 0 End End |
| ||
ReadPixels seems to be reading from the bottom of the screen not the top (a common problem in OpenGL). |
| ||
I doubt that's reading from the bottom because I can see the correct color values in the right places in the data buffer but the only thing that's different is the alpha value which is 0 and should be 255. run the code and look at the output. it displays the three color on the upper corner. it saves them to the data buffer but with the alpha value of 0. and when I draw them to the image it is obvious that it is not being drawn correctly. Clecius what are you trying to do? can you just draw directly to an image and extract the data buffer from it? I am thinking that it might be fast enough for what you are doing and I am guessing it will include the alpha value. Just guessing. Don't really know. |
| ||
You're not in 16-bit colour by any chance? |
| ||
Well observed Skid, the reading of ReadPixels is reversed. I made a dump from the array to confirm. Jesse I found that reading from the PeekBytes is really odd, so I made two functions to convert the Int values. I am building a routine to analise the pixel pattern from an image. And I intend to use the Canvas to draw on a image and not to the screen, this was just a POC. Many thanks, people! =D Strict Import mojo2 Import brl.filestream Function Main:Int() New Game() Return 0 End Class Game Extends App Field canvas:Canvas Field scrW:Int = 60 Field scrH:Int = 40 Method OnCreate:Int() SetDeviceWindow(scrW, scrH, 0) SetUpdateRate(60) canvas = New Canvas() canvas.SetProjection2d(0, scrW, 0, scrH) Return 0 End Method OnRender:Int() Local pixscan:DataBuffer = New DataBuffer((scrW * scrH) *4) Local colors:Int[] Local rgba:Int[] Local d_rgba:Int[] Local dump:FileStream rgba = rgba.Resize((scrW * scrH) *4) colors = colors.Resize(scrW * scrH) canvas.Clear() canvas.SetColor(1, 0, 0) canvas.DrawPoint(1, 0) canvas.SetColor(0, 1, 0) canvas.DrawPoint(2, 0) canvas.SetColor(0, 0, 1) canvas.DrawPoint(3, 0) canvas.SetColor(0.2, 0.4, 0.6) canvas.DrawPoint(58, 0) canvas.SetColor(1, 1, 1) canvas.DrawPoint(59, 0) canvas.Flush() canvas.ReadPixels(0, 0, scrW, scrH, pixscan, 0, 0) pixscan.PeekBytes(0, rgba) pixscan.PeekInts(0, colors) dump = New FileStream("rgba.dump", "w") For Local i:Int = EachIn rgba dump.WriteString(i+ ",") Next dump.Close() dump = New FileStream("colors.dump", "w") For Local i:Int = EachIn colors dump.WriteString(i+ ",") Next dump.Close() dump = New FileStream("colorstorgb.dump", "w") For Local i:Int = EachIn colors d_rgba = ColorToRgb(i) dump.WriteString(d_rgba[0]+","+d_rgba[1]+","+d_rgba[2]+","+d_rgba[3]+ "|") Next dump.Close() DebugStop() Return 0 End Function ColorToRgb:Int[](value:Int) Local resp:Int[] Local v:Int resp = resp.Resize(4) v = value resp[3] = v & 255 v = v Shr 8 resp[2] = v & 255 v = v Shr 8 resp[1] = v & 255 v = v Shr 8 resp[0] = v & 255 Return resp End Function RgbToColor:Int(a:Int, r:Int, g:Int, b:Int) Local v:Int = 0 v = v | a v = v Shl 8 v = v | r v = v Shl 8 v = v | g v = v Shl 8 v = v | b Return v End End |
| ||
Garry, Highly doubt it. Clecius, be careful when reading bytes. You have to be aware of big Endian and little Endian. what you are doing might be correct in windows but might not work on a Mac or other targets. Windows write integers one way while Macs writes integers in reverse of Windows. when you are try to extract bytes from bytes that were originally stored as integers, you might not get exactly what you want. if you are just going to work on Windows always, you won't need to worry about it though. |
| ||
. |
| ||
Good point, Jesse. I'm just starting with this tool, but I will keep this in mind for when advancing to other plataforms. Garry, I forgot in mention your comment on the last post. Sorry. I'm sure in 32 bit. ;-) Thanks again. |