RealBasic: Canvas tutorial lesson 3 Detecting pixel precise click/touch in irregular shapes

Here is a little trick to do a very fast pixel precise detection of a click/touch within a irregular shape without doing complicated calculations.

It’s a trick I use a lot in Realbasic, but is also usable in other languages like Basic4Android. By using a color map, you can get pixel precise detection very simple.

Let’s say we want to make a nice round menu. Make a second picture with exactly the same dimensions, but now we are going to draw the ‘click’ parts.
Give every clickable area another color. For our example, it look something like this:

Note: Make sure the map picture is 32-bit! This is needed for Basic4Android because if we use a 24-bit picture, Android messes with the colors.

You can check if a picture is 32 bit by right-clicking on the file, select properties and pick the details tab:

You can use a free tool like gimp to convert a 24 bit png to a 32 bit png.

In gimp, add a transparent layer and save the picture:

And now for the coding. I’ll show it in both Realbasic and Basic4Android:


MouseDown(X as integer, Y as integer) As Boolean
  Select case CircMenuMap32Bit.Graphics.Pixel(x,y)
  case &cFF0000
    StaticText1.caption = "Clicked on Recycle"
  case &cFFFF00
    StaticText1.caption = "Clicked on Film roll"
  case &c00FF00
    StaticText1.caption = "Clicked on Rubik cube"
  case &c00FFFF
    StaticText1.caption = "Clicked on Old Radio"
  case &c0000FF
    StaticText1.caption = "Clicked on Record player"
  case &cFF00FF
    StaticText1.caption = "Clicked on Box with stuff"
  case &cFFC0C0
    StaticText1.caption = "Clicked on Old TV"
  case &cFFFFC0
    StaticText1.caption = "Clicked on Folder with pictures"
  case &cC0FFC0
    StaticText1.caption = "Clicked on LadyBug"
  case &CFFFFFF
    StaticText1.caption = "Clicked on Big Button"
  End Select
End function

You can do a similar thing in the MouseMove() event:

Sub MouseMove(X as integer, Y as integer)
  Select case CircMenuMap32Bit.Graphics.Pixel(x,y)
  case &c000000
    me.MouseCursor = System.Cursors.StandardPointer
  case else
    me.MouseCursor = System.Cursors.FingerPointer
  End Select
End Sub

In Basic4Android:

Sub Panel1_Touch (Action As Int, X As Float, Y As Float)
	If action = activity.ACTION_DOWN Then
		Dim c As Int
		c = bmp.GetPixel(x,y)
		Select c
		Case Colors.RGB(255,0,0)
			label1.Text = "Clicked on Recycle"
		Case Colors.RGB(255,255,0)
			label1.Text ="Clicked on Film roll"
		Case Colors.RGB(0,255,0)
			label1.Text ="Clicked on Rubik cube"
		Case Colors.RGB(0,255,255)
			label1.Text ="Clicked on Old Radio"
		Case Colors.RGB(0,0,255)
			label1.Text ="Clicked on Record player"
		Case Colors.RGB(255,0,255)
			label1.Text ="Clicked on Box with stuff"
		Case Colors.RGB(255,192,192)
			label1.Text ="Clicked on Old TV"
		Case Colors.RGB(255,255,192)
			label1.Text ="Clicked on Folder with pictures"
		Case Colors.RGB(192,255,192)
			label1.Text ="Clicked on Ladybug"
		Case Colors.RGB(255,255,255)
			label1.Text ="Clicked on Big Button"
		Case Else
			label1.Text =""
		End Select
	End If
End Sub

And that’s it! Pretty simple no?

The realbasic source:
The Basic4Android source:

See you!

Click here to Donation if you like my work


About Alwaysbusy

My name is Alain Bailleul and I'm the Senior Software Architect/Engineer at One-Two. I like to experiment with new technologies, Computer Vision and A.I. My projects are programmed in B4X , Xojo, C#, java, HTML, CSS and JavaScript. View all posts by Alwaysbusy

10 responses to “RealBasic: Canvas tutorial lesson 3 Detecting pixel precise click/touch in irregular shapes

  • Mike

    Very nice tutorial. Thanks!

  • Jason Adams

    Interesting. So you’re never actually loading the map itself as visible in any form, but relying on its exactness in shape and size. So you use the x, y coordinates intended for another picture on the map itself… I like. šŸ™‚

    I am a bit curious, though. Could you elaborate a bit more as to why it’s important to use 32-bit in this matter?

    • Alwaysbusy

      This is only important for Android. A pixel in 24bit picture has a Red/Green/Blue, but Android uses a 32bit format where a pixel is Alpha/Red/Green/Blue. For some weird reason Android converts the 24bit picture to 32bit but does a calculation for the Alpha value (how it is done, I will try to find out. I would think you just use 255 for the alpha value but Android does something else.)

      The result is that e.g. RGB(255,192,192) in a 24-bit picture is sometimes another shade of that color like ARGB(255,255,189,189) in the 32bit picture. For our purspose that does not work: we do need exact values.

  • Andy Vermeulen

    Looks nice.

    Can you make a clickable area in GIMP?
    Tell me how..

  • Alex Silva

    Thank you very much for the tuts!!!

  • Jordan

    Wow! Pretty cool trick. Once I read through it I thought it was brilliant!!

  • Brian OBrien

    What would you do if your canvas objects were not fixed in one position. Your pixel map would need to be regenerated to handle situations where the object is clicked and dragged to a new location.

    • Alwaysbusy

      This would need some work, but you could indeed combine this technique with the Realbasic Dragging tutorials. You make a ‘colorMask’ picture that follows the dragging on an offscreen canvas. Every element would need a unique color.

      This offscreen canvas would need to implement a big part of the framework of the Dragging tutorials (e.g. the parts that only redraw a certain part of the canvas).

      Whenever something moves on the visible canvas, the offscreen canvas would need to follow. When you do a mousedown/move on the visible canvas, you check it with the offscreen canvas like in this tutorial.

      If you use the techniques in the Dragging tutorials, you would not need to worry about speed. 12Work is far more complicated than this and runs very well in full HD even on some older computers.

  • kusmadi

    Hi bro, how do I can write on panels (basic4android) such as the following applications

    Give me example please. Thanks so much

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: