ReadPixels - HTML5 Values Don't Match

Monkey Forums/Monkey Bug Reports/ReadPixels - HTML5 Values Don't Match

NoOdle(Posted 2012) [#1]
The pixels read from the current render buffer do not match the ARGB of the pixels that were drawn. I am running Safari 5.1.7 on Mac OS X Lion 10.7.4


marksibly(Posted 2012) [#2]
Hi,

Runnable sample code please?

But note that in general you may not be able to read back exactly what you've written. Monkey has no control over the pixel format of the back buffer (eg: it may only be 16 bit) or any filtering or scaling used by the renderer.


NoOdle(Posted 2012) [#3]
the image file I used is one I found from a google search:

The error does not happen on the Flash, IOS or GLFW target.

[monkeycode]
Strict
Import mojo



Class MyApp Extends App

Global background_r : Int = 255
Global background_g : Int = 0
Global background_b : Int = 128

Field sonic1 : Image
Field sonic2 : Image
Field saved : Bool = False


Method OnCreate : int()

SetUpdateRate( 60 )

sonic1 = LoadImage( "sonic.png" )

Return 0

End Method



Method OnUpdate : int()
Return 0
End Method



Method OnRender : int()
Cls background_r, background_g, background_b

DrawImage sonic1, 0, 0

Local w : Int = sonic1.Width()
Local h : Int = sonic1.Height()


Local pixels : Int[ w * h ]
ReadPixels( pixels, 0, 0, w, h )

PixelArrayMask( pixels, background_r, background_g, background_b )

If saved = False
saved = True

Local pList : List< String > = PixelArrayListColors( pixels )
For Local this : String = Eachin pList
Print this
Next

PixelArrayReplaceColour( pixels, 32, 32, 160, 32, 160, 32 )
PixelArrayReplaceColour( pixels, 32, 64, 192, 64, 192, 32 )
PixelArrayReplaceColour( pixels, 64, 64, 224, 64, 224, 64 )
PixelArrayReplaceColour( pixels, 96, 96, 224, 96, 224, 96 )

sonic2 = CreateImage( w, h )
sonic2.WritePixels( pixels, 0, 0, w, h )
Endif

SetColor 0, 0, 0
DrawRect 0, 0, w * 2, h

If sonic2
SetColor 255, 255, 255
DrawImage sonic2, w, 0
Endif

Return 0

End Method


End Class



Function Main : Int()
New MyApp()
Return 0
End Function





Function PixelArrayListColors : List< String >( pixels : Int[])
Local colors : List< String > = New List< String >
Local this : String = ""
For Local i : Int = 0 Until pixels.Length
Local argb : Int = pixels[ i ]
Local a : Int = ( argb Shr 24 ) & $ff
Local r : Int = ( argb Shr 16 ) & $ff
Local g : Int = ( argb Shr 8 ) & $ff
Local b : Int = argb & $ff
this = r + ", " + g + ", " + b
Local found : Bool = False
For Local c : String = Eachin colors
If this = c
found = True
Exit
Endif
Next
If found = False Then colors.AddLast( this )
Next
Return colors
End Function




'// Converts Mask Pixel Color to Transparent Pixel
Function PixelArrayMask : void( pixels : Int[], mask_r : Int = 0, mask_g : Int = 0, mask_b : Int = 0 )
For Local i : Int = 0 Until pixels.Length
Local argb : Int = pixels[ i ]
Local a : Int = ( argb Shr 24 ) & $ff
Local r : Int = ( argb Shr 16 ) & $ff
Local g : Int = ( argb Shr 8 ) & $ff
Local b : Int = argb & $ff
If a = 255 And r = mask_r And g = mask_g And b = mask_b
a = 0
argb = ( a Shl 24 ) | ( r Shl 16 ) | ( g Shl 8 ) | b
pixels[ i ] = argb
Endif
Next
End Function


'// Replaces a Pixel Colour
Function PixelArrayReplaceColour : void( pixels : Int[], old_r : Int, old_g : Int, old_b : Int, new_r : Int, new_g : Int, new_b : Int )
For Local i : Int = 0 Until pixels.Length
Local argb : Int = pixels[ i ]
Local a : Int = ( argb Shr 24 ) & $ff
Local r : Int = ( argb Shr 16 ) & $ff
Local g : Int = ( argb Shr 8 ) & $ff
Local b : Int = argb & $ff
If r = old_r And g = old_g And b = old_b
r = new_r
g = new_g
b = new_b
argb = ( a Shl 24 ) | ( r Shl 16 ) | ( g Shl 8 ) | b
pixels[ i ] = argb
Endif
Next
End Function


'// Replaces a Pixel Colour
Function PixelArrayReplaceColour : void( pixels : Int[], old_a : Int, old_r : Int, old_g : Int, old_b : Int, new_a : Int, new_r : Int, new_g : Int, new_b : Int )
For Local i : Int = 0 Until pixels.Length
Local argb : Int = pixels[ i ]
Local a : Int = ( argb Shr 24 ) & $ff
Local r : Int = ( argb Shr 16 ) & $ff
Local g : Int = ( argb Shr 8 ) & $ff
Local b : Int = argb & $ff
If a = old_a And r = old_r And g = old_g And b = old_b
a = new_a
r = new_r
g = new_g
b = new_b
argb = ( a Shl 24 ) | ( r Shl 16 ) | ( g Shl 8 ) | b
pixels[ i ] = argb
Endif
Next
End Function
[/monkeycode]


marksibly(Posted 2012) [#4]
Hi,

What's it meant to do/what is it doing?


NoOdle(Posted 2012) [#5]
Its supposed to swap the colours of sonics body from blue, to green. Works fine on FLASH, IOS and GLFW but on HTML5 the colour values returned are not the same as on the other targets so sonic stays blue.

I was seeing how feasible it was to implement colour palettes for game sprites and noticed this.


marksibly(Posted 2012) [#6]
Hi,

Actually, it's working here on both Chrome/Safari on MacOS 10.8 - ie: sonic is converted from blue to green.

Not sure what's up - can you try Chrome?

[edit]Just tried Snow Leopard and it's not working, even in Chrome. I would put this down to html5 just being html5! It's gonna be a while until this stuff works reliably everywhere.[/edit] Also works on Win7.

Also note that alpha will probably always read back as 255 using ReadPixels, as back buffers probably don't have an alpha channel.


therevills(Posted 2012) [#7]
Works fine here on Windows with FF and Chrome.


NoOdle(Posted 2012) [#8]
I would put this down to html5 just being html5!

Ok thanks, I was wondering if that was the case!

[edit] Oh btw, therevills, I nicked the mask code from you and modified it a bit, hope you don't mind :)