Android Question How crop with b4xcanvas and a trasparent color?

Alejandro Moyano

Member
Licensed User
Hi i'm developing a function to mask the sides of a panel.

The idea is have a function to choose wich corner will be rounded and round it trow a mask, and use it on my projects like this one:

activity.PNG

As you see are three XUIImageButtons (my customview, with the left corner line on) and should be rounded by a mask, i could use the Erel code direcly but im trying to build styling functions to use in all my projects.

EDIT: as i figure now, it may work for another cases but not like this as the mask will cover the back panel. Anyway the ask remains.

Im using b4j for kick b4x function develop, it will be used on b4a.

After start to work base on this Erel code base: https://www.b4x.com/android/forum/threads/panel-views-rounded-corners.69949/ but i can't apply the transparent color.

This is the form image:
form.PNG

and on execution:
exec.PNG

It should show an orange arc one the top corner but doesn't , am i doing somethig bad?

Here is the code:
B4X:
Sub Class_Globals
    Private fx As JFX
    Private xui As XUI
    Private mBase As B4XView
    Private canvas As B4XView
    Private radius As Int = 20dip
    Private BackgroundColor As Int = xui.Color_Red
    'Private mask As B4XCanvas
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(base As B4XView)
    mBase = base
    mBase.LoadLayout("1")
    canvas.AddView(CreateMask(canvas.Height,canvas.Width),0,0,canvas.Width,canvas.Height)
End Sub


'returns the equivalente an imageview witha bmp
Private Sub CreateMask(Height As Int, Width As Int) As B4XView
    Dim mask As B4XCanvas
    mask.Initialize(CreatePane)
    mask.Resize(Width,Height)
  
    'paint
    Dim p_left_top, p_left_bottom As B4XPath
    Dim r,r2 As B4XRect
    r.Initialize(0, 0, Width, Height)
    r2.Initialize(0, 0, Width, Height)
  
    'background
    mask.DrawRect(r,BackgroundColor,True,1dip)
    mask.Invalidate
  
    'left-top corner
    p_left_top.InitializeArc(radius,radius,radius,180,90)
    mask.ClipPath(p_left_top)
    mask.DrawRect(r2,xui.Color_Transparent,True,1dip)
    'mask.DrawPath(p_left_top,xui.Color_Green,True,1dip)
  
    'commit painting, get the bitmap and create the imageview
    mask.Invalidate
    Dim bmp As B4XBitmap = mask.CreateBitmap
    Dim pane As B4XView = CreateImagePane(Height,Width)
    pane.SetBitmap(bmp)
    Return pane
End Sub

'create a pane from the primitives
Private Sub CreatePane As B4XView
    #If b4a
        'nada
    #Else if b4j
        Dim pane As Pane
        pane.Initialize("")
        Return pane
    #End If
End Sub

'create a pane from the primitives width sizes
Private Sub CreateImagePane(Height As Int, Width As Int) As B4XView
    #If b4a
        'nada
    #Else if b4j
        Dim pane As ImageView
        pane.Initialize("")
        pane.SetSize(Width,Height)
        Return pane
    #End If
End Sub
 

Attachments

Last edited:

Alejandro Moyano

Member
Licensed User
The layout:
the_layout.PNG

How should looks:
how_should_looks.PNG

How looks at runtime:
how _looks_at_runtime.PNG

The function to be used to mask the panel:
B4X:
Sub Class_Globals
    Private fx As JFX
    Private xui As XUI
    Private mBase As B4XView
    Private canvas As B4XView
    'Private mask As B4XCanvas
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(base As B4XView)
    mBase = base
    mBase.LoadLayout("1")
    canvas.AddView(CreateMask(canvas.Height,canvas.Width,True,True,False,False, xui.Color_Black,20dip),0,0,canvas.Width,canvas.Height)
End Sub


'returns an imageview with a bmp mask of the selected corners
'size of the canvas, the selected corners, backgound color and the radius
'doesn't work and when i resize the mask, in androy may work great as the activity is recreated, not in b4i and b4j
Private Sub CreateMask(Height As Int, Width As Int, top_left As Boolean, _
                        top_rigth As Boolean, bottom_left As Boolean, bottom_right As Boolean, BackgroundColor As Int, radius As Int) As B4XView
    Dim mask As B4XCanvas
    mask.Initialize(xui.CreatePanel(""))
    mask.Resize(Width,Height)
   
    'paint
    Dim p_left_top, p_left_bottom, p_right_top, p_right_bottom, p_medium_square, p_larger_square As B4XPath
    Dim r, medium_square, larger_square As B4XRect
    r.Initialize(0, 0, Width, Height)

    'background
    mask.DrawRect(r,BackgroundColor,True,1dip)
   
    'left-top corner
    If top_left Then
        p_left_top.InitializeArc(radius,radius,radius,180,90)
        mask.ClipPath(p_left_top) '<-- i Try To crop instead paint, but doesnt work.
        'mask.DrawPath(p_left_top,xui.Color_Green,True,1dip)
    Else
        p_left_top.InitializeArc(radius,radius,radius*2,180,90) ' <- i does this instead pain an square with rect
        mask.ClipPath(p_left_top) '<-- i Try To crop instead paint, but doesnt work.
        'mask.DrawPath(p_left_top,xui.Color_Green,True,1dip)
    End If
   
    'left-bottom
    If bottom_left Then
        p_left_bottom.InitializeArc(radius,Height-radius,radius,90,90)
        mask.ClipPath(p_left_bottom) '<-- i try to crop instead paint, but doesnt work.
        'mask.DrawPath(p_left_bottom,xui.Color_Green,True,1dip)
    Else
        p_left_bottom.InitializeArc(radius,Height-radius,radius*2,90,90)
        mask.ClipPath(p_left_bottom)' <-- i try to crop instead paint, but doesnt work.
        'mask.DrawPath(p_left_bottom,xui.Color_Green,True,1dip)
    End If
   
    'right-top corner
    If top_rigth Then
        p_right_top.InitializeArc(Width-radius,radius,radius,270,90)
        mask.ClipPath(p_right_top) '<-- i try to crop instead paint, but doesnt work.
        'mask.DrawPath(p_right_top,xui.Color_Green,True,1dip)
    Else
        p_right_top.InitializeArc(Width-radius,radius,radius*2,270,90)
        mask.ClipPath(p_right_top) '<-- i try to crop instead paint, but doesnt work.
        'mask.DrawPath(p_right_top,xui.Color_Green,True,1dip)
    End If
   
    'right-bottom corner
    If bottom_right Then
        p_right_bottom.InitializeArc(Width-radius,Height-radius,radius,0,90)
        mask.ClipPath(p_right_bottom) '<-- i try to crop instead paint, but doesnt work.
        'mask.DrawPath(p_right_bottom,xui.Color_Green,True,1dip)
    Else
        p_right_bottom.InitializeArc(Width-radius,Height-radius,radius*2,0,90)
        mask.ClipPath(p_right_bottom) '<-- i try to crop instead paint, but doesnt work.
        'mask.DrawPath(p_right_bottom,xui.Color_Green,True,1dip)
    End If
   
   
    'medium square
    medium_square.Initialize(0,radius,Width,Height-radius)
    p_medium_square.Initialize(0,radius)
    p_medium_square.InitializeRoundedRect(medium_square,0)
    mask.ClipPath(p_medium_square) '<-- i try to crop instead paint, but doesnt work.
    'mask.DrawPath(p_medium_square,xui.Color_Green,True,1dip)
   
    'larger square
    larger_square.Initialize(radius,0,Width-radius,Height)
    p_larger_square.Initialize(radius,0)
    p_larger_square.InitializeRoundedRect(larger_square,0)
    mask.ClipPath(p_larger_square) '<-- i try to crop instead paint, but doesnt work.
    'mask.DrawPath(p_larger_square,xui.Color_Green,True,1dip)
   
    'commit painting, get the bitmap and create the imageview
    mask.Invalidate
    Dim bmp As B4XBitmap = mask.CreateBitmap
    Dim pane As B4XView = CreateImagePanel(Height,Width)
    pane.SetBitmap(bmp)
    Return pane
End Sub

'create a panel from the primitives width sizes
Private Sub CreateImagePanel(Height As Int, Width As Int) As B4XView
    #If b4a
        'nada
    #Else if b4j
        Dim pane As ImageView
        pane.Initialize("")
        pane.SetSize(Width,Height)
        Return pane
    #End If
End Sub
Excuses my english, is not my main language but i'm working on it.
 

Attachments

Erel

Administrator
Staff member
Licensed User
I hope that this will help you:



B4X:
Sub AppStart (Form1 As Form, Args() As String)
   MainForm = Form1
   MainForm.RootPane.LoadLayout("1") 'Load the layout file.
   MainForm.Show
   Dim bmp As B4XBitmap = xui.LoadBitmapResize(File.DirAssets, "114867.jpg", ImageView1.Width, ImageView1.Height, False)
   ImageView1.SetBitmap(MakeRoundCorners(bmp, False, True, True, True, 20dip))
   ImageView2.SetBitmap(MakeRoundCorners(bmp, False, True, True, True, 20dip))
   ImageView3.SetBitmap(MakeRoundCorners(bmp, False, False, True, True, 20dip))
   ImageView4.SetBitmap(MakeRoundCorners(bmp, False, True, False, False, 20dip))
End Sub


Sub MakeRoundCorners(bmp As B4XBitmap, TopLeft As Boolean, TopRight As Boolean, BottomLeft As Boolean, BottomRight As Boolean, Radius As Int) As B4XBitmap
   Dim bcbrush As BitmapCreator
   bcbrush.Initialize(bmp.Width, bmp.Height)
   bcbrush.CopyPixelsFromBitmap(bmp)
   Dim bc As BitmapCreator
   bc.Initialize(bmp.Width + 1, bmp.Height + 1)
   Dim brush As BCBrush = bcbrush.CreateBrushFromBitmapCreator(bcbrush)
   Dim r As B4XRect
   r.Initialize(0, 0, bc.mWidth - 1, bc.mHeight - 1)
   bc.DrawRectRounded2(r, brush, True, 0, Radius)
   If TopLeft = False Then
       r.Initialize(0, 0, Radius, Radius)
       bc.DrawRect2(r, brush, True, 0)
   End If
   If TopRight = False Then
       r.Initialize(bc.mWidth - Radius, 0 , bc.mWidth, Radius)
       bc.DrawRect2(r, brush, True, 0)
   End If
   If BottomRight = False Then
       r.Initialize(bc.mWidth - Radius, bc.mHeight - Radius , bc.mWidth, bc.mHeight)
       bc.DrawRect2(r, brush, True, 0)
   End If
   If BottomLeft = False Then
       r.Initialize(0, bc.mHeight - Radius, Radius, bc.mHeight)
       bc.DrawRect2(r, brush, True, 0)
   End If
   Return bc.Bitmap
End Sub
 
Top