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. |