Android Question [B4X] How to reuse canvas

Alexander Stolte

Expert
Licensed User
Longtime User
I would like to know how to continue using a B4XCanvas for another panel e.g. if I add another panel to a xCustomListView.

Example:
B4X:
    For i = 0 To 100 -1
        
        Dim xpnl As B4XView = xui.CreatePanel("")
        xpnl.SetLayoutAnimated(0,0,0,Root.Width,400dip)
        xpnl.Color = xui.Color_ARGB(255,Rnd(0,256),Rnd(0,256),Rnd(0,256))
        
        Dim xpnl_Canvas As B4XView = xui.CreatePanel("")
        xpnl.AddView(xpnl_Canvas,0,0,xpnl.Width,xpnl.Height)
        
        Dim xcv As B4XCanvas
        xcv.Initialize(xpnl_Canvas)
        xcv.DrawLine(0,0,xpnl.Width,0,xui.Color_Red,10dip)
        
        xCLV.Add(xpnl,"")
        
    Next
 

Attachments

  • B4XPages.zip
    8.6 KB · Views: 91

Alexander Stolte

Expert
Licensed User
Longtime User
Make the drawing you need, call B4XCanvas.CreateBitmap and add the bitmap to a (B4X)ImageView.
But if i do this way, then i have this:
1648982833484.png

All lines are drawn with 255 white, but not all look 255 white, some are faded. Why is this? and is there a way to fix this?
B4X:
    Dim xpnl_Canvas As B4XView = xui.CreatePanel("")
    xpnl_Canvas.SetLayoutAnimated(0,0,0,Root.Width,Root.Height)
   
    Dim xcv As B4XCanvas
    xcv.Initialize(xpnl_Canvas)
   
    Dim DayWidth As Float = Root.Width/7
    Dim BlockHeight As Float = Root.Height/48
   
    For i = 0 To 7 -1
        'Draw Vertical lines
        If i <> 0 Then
            xcv.DrawLine(DayWidth*i,0,DayWidth*i,Root.Height,xui.Color_White,1dip)
        End If
   
    Next
   
    'Draw Horizontal lines
    For i = 1 To 49 -1
        xcv.DrawLine(0,BlockHeight*i,Root.Width,BlockHeight*i,xui.Color_White,1dip)
    Next

    Dim GridBitmap As B4XBitmap = xcv.CreateBitmap
   
   
    For i = 0 To 100 -1
       
        Dim xpnl As B4XView = xui.CreatePanel("")
        xpnl.SetLayoutAnimated(0,0,0,Root.Width,Root.Height)
        'xpnl.Color = xui.Color_ARGB(255,Rnd(0,256),Rnd(0,256),Rnd(0,256))
        xpnl.Color = xui.Color_Black
       
        Dim xiv As ImageView
        xiv.Initialize("")
        xpnl.AddView(xiv,0,0,xpnl.Width,xpnl.Height)
       
        xiv.As(B4XView).SetBitmap(GridBitmap)
       
        xCLV.Add(xpnl,"")
       
    Next
 

Attachments

  • B4XPages.zip
    8.8 KB · Views: 101
Upvote 0

Alexander Stolte

Expert
Licensed User
Longtime User
Switching to BitmapCreator is faster and the result is much better, but the problem is still there:
1648983628979.png

Some lines are darker
B4X:
Private Sub Effizient
    
    Dim Date As Long = DateTime.Now
    
    'Dim xpnl_Canvas As B4XView = xui.CreatePanel("")
    'xpnl_Canvas.SetLayoutAnimated(0,0,0,Root.Width,Root.Height)
    
    Dim bc As BitmapCreator
    bc.Initialize(Root.Width,Root.Height)
    
'    Dim xcv As B4XCanvas
'    xcv.Initialize(xpnl_Canvas)
    
    Dim DayWidth As Float = Root.Width/7
    Dim BlockHeight As Float = Root.Height/48
    
    For i = 0 To 7 -1
        'Draw Vertical lines
        If i <> 0 Then
            'xcv.DrawLine(DayWidth*i,0,DayWidth*i,Root.Height,xui.Color_ARGB(100,255,255,255),1dip)
            bc.DrawLine(DayWidth*i,0,DayWidth*i,Root.Height,xui.Color_ARGB(255,255,255,255),1dip)
        End If
    
    Next
    
    'Draw Horizontal lines
    For i = 1 To 49 -1
        'xcv.DrawLine(0,BlockHeight*i,Root.Width,BlockHeight*i,xui.Color_ARGB(100,255,255,255),1dip)
        bc.DrawLine(0,BlockHeight*i,Root.Width,BlockHeight*i,xui.Color_ARGB(255,255,255,255),1dip)
    Next

    Dim GridBitmap As B4XBitmap = bc.Bitmap'xcv.CreateBitmap
    Log((DateTime.Now - Date)  & "ms")
    
    For i = 0 To 50 -1
        
        Dim xpnl As B4XView = xui.CreatePanel("")
        xpnl.SetLayoutAnimated(0,0,0,Root.Width,Root.Height)
        'xpnl.Color = xui.Color_ARGB(255,Rnd(0,256),Rnd(0,256),Rnd(0,256))
        xpnl.Color = xui.Color_Black
        
        Dim xiv As ImageView
        xiv.Initialize("")
        xpnl.AddView(xiv,0,0,xpnl.Width,xpnl.Height)
        
        xiv.As(B4XView).SetBitmap(GridBitmap)
        
        xCLV.Add(xpnl,"")
        
    Next
    
    Log((DateTime.Now - Date)  & "ms")
    
End Sub
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
You would have to look at anti-aliasing algorithms (not recommended reading).

A hint is that the sub-pixel offset of .5 places the line so that the drawn pixels positions are now adjusted to the next available integral position.
The anti-aliasing algorithm has nothing to do.

Another hint is that this works only for vertical and horizontal lines. It does not turn off anti-aliasing.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
I haven't tried it, but does it also work if you just cast the parameters to .draw to .As(Int)?

Remember Round(X) = Floor(X + .5)

Just curious.

[Also, if it it does maybe you could post that as a solution to a new question, so others can find it.]
 
Upvote 0
Top