iOS Question BitmapCreator FillRadialGradient error!

cxbs

Active Member
Licensed User
Longtime User
Hello everyone!

I want to draw gradient segments at any angle,

Refer to this example

But drawing more times will make the following mistakes
Out of bounds. Index=? Length=?
error.jpg


B4X:
#Region  Project Attributes
    #ApplicationLabel: B4i Example
    #Version: 1.0.0
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
    #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
    #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
    #Target: iPhone, iPad
    #ATSEnabled: True
    #MinVersion: 8
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
    'Private xui As XUI
    Private ImageView1 As ImageView
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.RootPanel.LoadLayout("Page1")
    NavControl.ShowPage(Page1)
End Sub

Sub Button1_Click
    'xui.MsgboxAsync("Hello world!", "B4X")
    Dim no As NativeObject
    ImageView1.Bitmap = no.Initialize ("UIImage").RunMethod ("new", Null)

    Dim Bc As BitmapCreator
    Bc.Initialize(ImageView1.Width, ImageView1.Height)
    Dim bc2 As BitmapCreator

    Dim x As Float,y As Float
    Dim x1 As Float,y1 As Float
    Dim x2 As Float,y2 As Float
    x=200
    y=300
    Dim w As Int=20
    For i=1 To 100
        x1=Rnd(-100,100)
        y1=Rnd(-100,100)
        x2=x+x1
        y2=y+y1
        Dim bc2 As BitmapCreator
        If x1<w Then
            If y1<w Then
                bc2.Initialize(w,w)
            Else
                bc2.Initialize(w,Abs(y1))
            End If
        Else
            If y1<w Then
                bc2.Initialize(Abs(x1),w)
            Else
                bc2.Initialize(Abs(x1),Abs(y1))
            End If
        End If
        bc2.FillRadialGradient(Array As Int(Colors.RGB(0,128,0),Colors.RGB(0,192,0)),bc2.TargetRect)
        Bc.DrawLine2(x, y, x2, y2, Bc.CreateBrushFromBitmapCreator(bc2), w)
        x=x2
        y=y2
    Next
    'Bc.SetBitmapToImageView(Bc.Bitmap,ImageView1)
    ImageView1.Bitmap=Bc.Bitmap
End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)
    ImageView1.SetLayoutAnimated(0,0,0,ImageView1.Top,Width,Height-ImageView1.Top)
End Sub

A gradient effect like this
img.jpg
 

Attachments

  • BitmapCreatorError.zip
    2.7 KB · Views: 134
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. Where does this strange code come from?
B4X:
Dim no As NativeObject
    ImageView1.Bitmap = no.Initialize ("UIImage").RunMethod ("new", Null)

2. The code is very inefficient.

3. Why is ImageView1 not anchored to BOTH sides?

This will help you get started:
1632636403267.png

B4X:
Sub Process_Globals
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
    Private xui As XUI
    Private ImageView1 As B4XView
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.RootPanel.LoadLayout("Page1")
    NavControl.ShowPage(Page1)
End Sub

Sub Button1_Click
    Dim Bc As BitmapCreator
    Bc.Initialize(ImageView1.Width, ImageView1.Height)
    
    Dim cx = Bc.mWidth / 2, cy = Bc.mHeight / 2 As Int
    Dim largeR As Int = Min(cx, cy) - 10
    Dim smallR As Int = 40
    
    Dim bc2 As BitmapCreator
    bc2.Initialize(largeR * 2, largeR * 2)
    bc2.FillRadialGradient(Array As Int(0xFFFF9D00, 0xFFFFFF00, 0xFFFF9D00),bc2.TargetRect)
    Dim brush As BCBrush = Bc.CreateBrushFromBitmapCreator(bc2)
    brush.SrcOffsetX = (Bc.mWidth - bc2.mWidth) / 2
    brush.SrcOffsetY = (Bc.mHeight - bc2.mHeight) / 2
    For angle = 0 To 359 Step 30
        Bc.DrawLine2(cx + smallR * SinD(angle), cy + smallR * CosD(angle), cx + largeR * SinD(angle), cy + largeR * CosD(angle), brush, 20)
    Next
    Bc.SetBitmapToImageView(Bc.Bitmap, ImageView1)
End Sub
 
Upvote 0

cxbs

Active Member
Licensed User
Longtime User
1. Where does this strange code come from?
B4X:
Dim no As NativeObject
    ImageView1.Bitmap = no.Initialize ("UIImage").RunMethod ("new", Null)

2. The code is very inefficient.

3. Why is ImageView1 not anchored to BOTH sides?

This will help you get started:
View attachment 119581
B4X:
Sub Process_Globals
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
    Private xui As XUI
    Private ImageView1 As B4XView
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.RootPanel.LoadLayout("Page1")
    NavControl.ShowPage(Page1)
End Sub

Sub Button1_Click
    Dim Bc As BitmapCreator
    Bc.Initialize(ImageView1.Width, ImageView1.Height)
   
    Dim cx = Bc.mWidth / 2, cy = Bc.mHeight / 2 As Int
    Dim largeR As Int = Min(cx, cy) - 10
    Dim smallR As Int = 40
   
    Dim bc2 As BitmapCreator
    bc2.Initialize(largeR * 2, largeR * 2)
    bc2.FillRadialGradient(Array As Int(0xFFFF9D00, 0xFFFFFF00, 0xFFFF9D00),bc2.TargetRect)
    Dim brush As BCBrush = Bc.CreateBrushFromBitmapCreator(bc2)
    brush.SrcOffsetX = (Bc.mWidth - bc2.mWidth) / 2
    brush.SrcOffsetY = (Bc.mHeight - bc2.mHeight) / 2
    For angle = 0 To 359 Step 30
        Bc.DrawLine2(cx + smallR * SinD(angle), cy + smallR * CosD(angle), cx + largeR * SinD(angle), cy + largeR * CosD(angle), brush, 20)
    Next
    Bc.SetBitmapToImageView(Bc.Bitmap, ImageView1)
End Sub

Dear Mr. Erel
Thank you very much for your help

Question 1: is the image displayed before each clearing

Question 2: I want to achieve the lgshaperender.rect4 (x as float, y as float, width as float, height as float, originx as float, originy as float, rotation as float, col1 as lgcolor, col2 as lgcolor, col3 as lgcolor, col4 as lgcolor) function of b4a, which can draw 100000 gradient segments per second

Q3: This is an example. I will pay attention to it later. Thank you for your reminder

I spent a long time testing the code you provided
Maybe I can't describe it clearly. I finally want to draw a picture of this effect
That is, the gradient angle changes according to the direction of the line segment
Is b4i difficult to achieve this effect
img.jpg

The above English comes from translation software
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. The way to implement such things, is to create a B4XPages and start with B4J.

1632667803572.png


This code shows how you can draw rotated gradients. Next step is to calculate the angle.

B4X:
Private Sub Panel1_Touch (Action As Int, X As Float, Y As Float)
    If Action = Panel1.TOUCH_ACTION_DOWN Then
        Dim task As DrawTask = bc1.CreateDrawTask(bc2, bc2.TargetRect, X, Y, True)
        task.Degrees = Rnd(0, 360)
        bc1.DrawBitmapCreatorTransformed(task)
        bc1.SetBitmapToImageView(bc1.Bitmap, ImageView1)
    End If
End Sub
 

Attachments

  • Project.zip
    8.5 KB · Views: 124
Upvote 0

cxbs

Active Member
Licensed User
Longtime User
1. The way to implement such things, is to create a B4XPages and start with B4J.

View attachment 119605

This code shows how you can draw rotated gradients. Next step is to calculate the angle.

B4X:
Private Sub Panel1_Touch (Action As Int, X As Float, Y As Float)
    If Action = Panel1.TOUCH_ACTION_DOWN Then
        Dim task As DrawTask = bc1.CreateDrawTask(bc2, bc2.TargetRect, X, Y, True)
        task.Degrees = Rnd(0, 360)
        bc1.DrawBitmapCreatorTransformed(task)
        bc1.SetBitmapToImageView(bc1.Bitmap, ImageView1)
    End If
End Sub

Dear Mr. Erel
Thank you very much for taking the time to write examples
After real machine test, it can draw 100000 times per second,
B4X:
Private Sub Button1_Click
    Dim x As Int,y As Int
    Dim w As Int=ImageView1.Width
    Dim h As Int=ImageView1.Height
    Dim task As DrawTask = bc1.CreateDrawTask(bc2, bc2.TargetRect, 0, 0, False)
    Button1.Text="Start"
    Sleep(0)
    Dim t As Long=DateTime.Now
    For i=1 To 100000
        x=Rnd(-100,w+100)
        y=Rnd(-100,h+100)
        task.TargetX=x
        task.TargetY=y
        task.Degrees = Rnd(0, 360)
        task.SrcScaleX=Rnd(2,100)/100
        bc1.DrawBitmapCreatorTransformed(task)
    Next
    bc1.SetBitmapToImageView(bc1.Bitmap, ImageView1)
    Msgbox(DateTime.Now-t,"run time")
    Button1.Text="Click"
End Sub
This is a perfect solution!
Thank you again for your help and wish you a happy life!
 
Upvote 0
Top