• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

Read one pixel

gontran

Member
Joined
Apr 27, 2020
Messages
31
Helo again , I try to find a simple form to read one pixel in my canvas. I don´t need to read a block off pixels.
How can I do this ?

I need to use a databuffer and readpixels function?
I´m using mojo2

Thanks for the help
 
Last edited:
A look into the docs gives you this

1593703853041.png
 
Ok now my problem is this I have
PantallaJuego.ReadPixels(dedox,dedoy,1,1,pixel1)
ok in pixel1 are databuffer. ok now I need to read the content. I try to use GET but cerberus say identifier get not found.
I'm little lost
How can I read the content in my databuffer?

Thanks for the help
 
I can't test here but it should be something like this.

You have a combination of 3 things, a canvas for input (reading pixels), a image for output (plotting), and a data buffer, because you this process is very visible and you need a data buffer to do both the plotting and reading.


Cerberus:
Import mojo2
Import brl

Class MyApp Extends App

    Field canvas:Canvas
    Field myCanvas:Canvas
    Field myImage:Image
    Field myData:DataBuffer
   
    Method OnCreate:Int()
        canvas = New Canvas()
       
        ' Set up a sprite that you can draw to
        myImage = New Image(256, 256)
        myCanvas = New Canvas(myImage)
        myData = New DataBuffer(256 * 256 * 4)  
    End
   
    Method OnRender:Int()

        ' Draw 256 x 256 green sprite
       
        myCanvas.Clear(0,1,0)

        ' Plot pixel
        myData.PokeInt(0,myData.PeekInt(0) & $00000000) ' Make a pixel in the sprite black (0 is mapped to x & y)
        myImage.WritePixels(0,0,1,1, myData)
        myCanvas.Flush()

        ' Read pixel
        myCanvas.ReadPixels(0,0,1,1,myData)
        Local value:Int = myData.PeekInt(0) ' Read a pixel in the sprite black (0 is mapped to x & y)
   
        ' ---------------------------------------
   
        ' Draw our canvas-image-combo, to main canvas
        canvas.SetBlendMode(BlendMode.Opaque2)
        canvas.Clear(0,0,0)
        canvas.DrawImage(myImage, 50,50)
        canvas.Flush()
    End
   
End

Function Main:Int()
    New MyApp()
End
 
Here is working example that writes and reads a pixel of a green sprite.


I don't know why it looks like there's black area around the pixel though but this is how you read and plot a pixel.

Cerberus:
Import mojo2
Import brl.databuffer

Class MyApp Extends App

    Field mainCanvas:Canvas
    Field myImage:Image
    Field myData:DataBuffer
    Field myCanvas:Canvas
    
    Method OnCreate:Int()
        mainCanvas = New Canvas()
        myImage = New Image(256, 256)
        myCanvas = New Canvas(myImage)
        myData = New DataBuffer(256 * 256 * 4)
    End
    
    Method OnRender:Int() 
        myCanvas.Clear(0,1,0)         

        ' Plot pixel
        myData.PokeInt(0, $ffffffff)
        myImage.WritePixels(0, 0, 1,1, myData)
        myCanvas.Flush() 
        
        ' Read pixel
        myCanvas.ReadPixels(0, 0, 1,1 myData)
        Local value:Int = myData.PeekInt(0)

        mainCanvas.SetBlendMode(BlendMode.Opaque2)
        mainCanvas.Clear()   
        mainCanvas.DrawImage(myImage, 200,200)
        mainCanvas.Flush()
    End
End

Function Main:Int()
    New MyApp()
    Return 0
End
readpixel.png
 
Ok but I dont whant to plot nothing I only need to read 1 pixel in canvas
I need to know the color in any type off data rgb or any.
If I use

Field pixel1: DataBuffer

on create()
pixel1 = New DataBuffer(1 * 1 * 4)

on render()
PantallaJuego.ReadPixels(dedox,dedoy,1,1,pixel1)
pixel2 = pixel1[0]

I have an error . say only strings and array are indexed
How can I read the data or convert to string or int ?

Thanks for the help
 
You need to use the code tag for code.
No look in the code. Also ignore the drawing if you do not want drawing.

The actual reading of the pixel is this line :
Cerberus:
Local value:Int = myData.PeekInt(0) ' This is the read

Here's another example, that also converts the pixel to a string
Cerberus:
Import mojo2
Import brl

Class MyApp Extends App

    Field mainCanvas:Canvas
    Field myImage:Image
    Field myData:DataBuffer
    Field myCanvas:Canvas

    Method OnCreate:Int()
        mainCanvas = New Canvas()
        myImage = New Image(256, 256)
        myCanvas = New Canvas(myImage)
        myData = New DataBuffer(256 * 256 * 4)
    End

    Method OnRender:Int()

        myCanvas.Clear(0,0.1,0) 
    
        ' Read all pixels so we can change a single pixel because reading and writing 1x1 area gives artefacts)
        myCanvas.ReadPixels(0,0,256,256,myData)
    
        ' Plot pixel
        myData.PokeInt(0,$ffffffff)
        myImage.WritePixels(0,0,256,256,myData)
        myCanvas.Flush()

        ' Read pixel
        Local value:Int = myData.PeekInt(0) ' This is the read
    
        ' To proove we read it, let's write a clone-pixel, 2 steps to the right
        myData.PokeInt(2*4,value)
        myImage.WritePixels(0,0,256,256,myData)
        myCanvas.Flush()

        Local myString:String = Int(value) ' Cast (meaning convert) the integer (which is the pixel we read) to a string

        mainCanvas.SetBlendMode(BlendMode.Opaque2)
        mainCanvas.Clear(0,0,0)
        mainCanvas.DrawImage(myImage,200,200)
          mainCanvas.DrawText "The pixel value is",200,200,.5,.5
        mainCanvas.DrawText myString,200,240,.5,.5
        mainCanvas.Flush()
    End
End

Function Main:Int()
    New MyApp()
End
 
I'm not sure that it's okay to access a small areas or even just a single pixel at a time. Look at the first example and see what happens when you write a pixel that way. I think the safest for both reading and writing pixels would be to read the whole buffer and after that access the one pixel you need using the peekInt instruction. It's not optimal but it works.
 
Thanks for the time, now works perfect, I really appreciate your time.
Other question is .
In the integer data, how I can know the red, green and blue and if this have the alpha.

Thanks for you´re help
 
It would help to write the value as hexadecimal instead of decimal.

The integer is 64 bit I guess but you use only the low 32 bits normally for graphics.
Here's how you create a value of your own using the trick of shifting bits.
Cerberus:
Local rgba:Int = a  Shl 24 | b Shl 16 | g Shl 8 | r

You can do the opposite when you read the pixel values, you can can divide the integer up into red, green, blue, and alpha parts.
 
If you need some help with this kind of tricks, this is how can do it.
You shift the original value as many steps as you need to get it to the lowest 8 bits, then you get only those 8 bits using AND logic.

Cerberus:
   a = rgba Shr 24) & $ff
   b = (rgba Shr 16) & $ff
   g = (rgba Shr 8) & $ff
   r = (rgba) & $ff
 
Hmm ok but again I´m confused, were :
Local rgba:Int = a Shl 24 | b Shl 16 | g Shl 8 | r
this got my peek data?

Thanks for the patience
 
I won't plot a pixel in this one to make it simpler, I just read the pixel of whatever happens to be there.
Hope this helps.
Cerberus:
Import mojo2
Import brl

Class MyApp Extends App

    Field mainCanvas:Canvas
    Field myImage:Image
    Field myData:DataBuffer
    Field myCanvas:Canvas

    Method OnCreate:Int()
        mainCanvas = New Canvas()
        myImage = New Image(256, 256)
        myCanvas = New Canvas(myImage)
        myData = New DataBuffer(256 * 256 * 4)
    End

    Method OnRender:Int()

        myCanvas.Clear(0,0.1,0)
        myCanvas.ReadPixels(0,0,256,256,myData) ' Step one is to read all pixels from canvas into buffer (myData)
        myCanvas.Flush()

        Local rgba:Int = myData.PeekInt(0)      ' Next step is to read pixel from the buffer
  
          Local a:Int = (rgba Shr 24) & $ff        ' Now check the pixel out
          Local b:Int = (rgba Shr 16) & $ff
          Local g:Int = (rgba Shr 8) & $ff
          Local r:Int = (rgba) & $ff

          Local myString:String = Int(a)             ' We want to print alpha of pixel
        
        mainCanvas.Clear(0,0,0)
        mainCanvas.DrawText myString,200,240,.5,.5
        mainCanvas.Flush()
    End
End

Function Main:Int()
    New MyApp()
End
 
Last edited:
Thanks again this works fine and is exactly what I need.

Regards
Gontran Noble V.
 
Hello again , ok this is very extrange. I think is because I use :
PantallaJuego.SetViewport(0, 0,canvasWidth,canvasHeight)
PantallaJuego.SetProjection2d(0, VWIDTH, 0, VHEIGHT)

if I try to read the pixel in my canvas , I see the pixel read is not in the position on my mouse or my finger , How is this posible?
Iny ideas ?

My problem is a game for android I try to set the bottons positions but there are many resolutions.


I would appreciate any idea
Thanks for the time
 
Sorry I can't help you there, I'm struggling with understanding how Cerberus-X deals with different resolutions myself right now.
 
Ok hello again. Now I solve my problem with the buttons and diferent resolutions. This is the idea

I have 4 buttons , aceleration , stop button, up and down
I develope my game in 1920 x 1080 resolution , then I know my 1st button are in x1 = 128 y1 = 769 x2 =256 y2=897
Ok if the android divece have other resolution I use % to reset de buttons position in the touch , not in my image not in my game
then it work

canvasWidth = DeviceWidth()
canvasHeight = DeviceHeight()
VWIDTH = 1920
VHEIGHT = 1080
de_128_ax = (canvasWidth * 100) / VWIDTH
de_128_ay = (canvasHeight * 100) / VHEIGHT
ace_x1 = ace_x1 * (de_128_ax/100)
ace_y1 = ace_y1 * (de_128_ay/100)
ace_x2 = ace_x2 * (de_128_ax/100)
ace_y2 = ace_y2 * (de_128_ay/100)

And voila it works :)
Regards
Gontran Noble V.
 
Back
Top Bottom