Android Question Led/pixel preview array issue

techknight

Well-Known Member
Licensed User
Longtime User
I had posted this in another thread, but it was a long running chain and probably got missed, And it deserves a new thread.

Basically, I created a 48x112 pixel preview window by using a label array. background red = on, background grey = off. These are loaded inside a panel. Here is the code, including some test code:

B4X:
Sub CreatePreviewWindow()
    Dim x As Int, y As Int
    Dim offsetX, offsetY As Int
    For X = 0 To 111 Step 1
        offsetX = (x * 7) + 25
        For y = 0 To 15 Step 1
            offsetY = (y * 7) + 25
            Dim L As Label
            L.Initialize("pixels")
            L.Background = PixelOff
            pnlPreview.AddView(L, offsetX, offsetY, 7, 7)
            Pixels1(x, y) = L
        Next
        For y = 0 To 15 Step 1
            offsetY = (y * 7) + 137
            Dim L As Label
            L.Initialize("pixels")
            L.Background = PixelOff
            pnlPreview.AddView(L, offsetX, offsetY, 7, 7)
            Pixels2(x, y) = L
        Next
        For y = 0 To 15 Step 1
            offsetY = (y * 7) + 249
            Dim L As Label
            L.Initialize("pixels")
            L.Background = PixelOff
            pnlPreview.AddView(L, offsetX, offsetY, 7, 7)
            Pixels3(x, y) = L
        Next
    Next
    'Test by setting some random pixels
    For X = 0 To 50 Step 1
        Pixels1(Rnd(0, 111), Rnd(0, 15)).Background = PixelOn
        Pixels2(Rnd(0, 111), Rnd(0, 15)).Background = PixelOn
        Pixels3(Rnd(0, 111), Rnd(0, 15)).Background = PixelOn
    Next
End Sub

I attached a photo of the subroutine loaded and what it looks like on the screen.

Works great, BUT... it is very very very horrifyingly slow when that thing is visible on the activity window. the whole GUI goes to 386 speeds. and everything becomes laggy and almost unresponsive. Also it takes a very long time for this subroutine to execute of course. But if you hide the panel in the background, everything is fine.

My assumption is because there are now 5,376 tiny little pixel size labels on the screen laid out in a grid, more than the UI rendering engine can handle.

After explaining what I am doing and its inherent problem, is there a more efficient way to layout a preview pixel grid?
 

Attachments

  • 20151117_143914.jpg
    20151117_143914.jpg
    295 KB · Views: 246

JordiCP

Expert
Licensed User
Longtime User
You should use an imageview with a mutablebitmap and draw the pixels with a canvas.

Let me look for a code I made for this. I'm back in 5 minutes
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Well, I had to redo a little bit but it works

Copy and paste it into a new project. Each time you click the screen it will change

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim IV As ImageView
    Dim B As Bitmap
    Dim numPixelsX As Int = 112
    Dim numPixelsY As Int = 48
    Dim IVSizeX,IVSizeY As Int
    Dim pixelRadius As Int
    Dim cv As Canvas
    Dim dist As Float 
    Dim COLOR_OFF As Int=Colors.Gray
    Dim COLOR_ON As Int = Colors.Yellow
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    IV.Initialize("IV")
   
    IVSizeX= 100%X
    IVSizeY= IVSizeX*numPixelsY/numPixelsX
    'We draw it at the top right
    Activity.AddView(IV,100%X - IVSizeX, 0%Y, IVSizeX,IVSizeY)
    B.InitializeMutable(IVSizeX,IVSizeY)
    IV.Bitmap=B
   
    CreatePreviewWindow
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub CreatePreviewWindow

    dist= IV.Width/numPixelsX
    pixelRadius=dist/2
    cv.Initialize2(B)
    cv.DrawColor(Colors.DarkGray)
    For y=0 To numPixelsY-1   
        For x=0 To numPixelsX-1
            cv.DrawCircle( dist/2 + x*dist, dist/2 + y*dist, pixelRadius, COLOR_OFF,True, 1)
        Next
    Next

End Sub


Sub SetPixelColor( x As Int, y As Int, Color As Int)

    cv.DrawCircle( dist/2 + x*dist, dist/2 + y*dist, pixelRadius, Color,True, 0)

End Sub

Sub FillRandom

    For row =0 To numPixelsY-1
        For column=0 To numPixelsX-1
            If Rnd(0,2)==0 Then
                SetPixelColor(column,row,COLOR_OFF)
            Else
                SetPixelColor(column,row,COLOR_ON)               
            End If
           
        Next
    Next
    IV.Invalidate
End Sub

Sub IV_Click
    CallSubDelayed(Me,"FillRandom")
End Sub
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
That works really well! However, How do I get it within the confines of my panel? have a look at my screenshot.
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Just change IVSizeX value to, for instance, 60%
Then, IVSizeY is calculated automatically to keep aspect ratio

The line
B4X:
Activity.AddView(IV,100%X - IVSizeX, 0%Y, IVSizeX,IVSizeY)
draws the IV at the top-right of your screen . Just change the values to your needs



--EDIT---

If you have already your panel created and want the IV to be inside the panel, just remove the line
B4X:
IVSizeX=100%
Activity.AddView(IV,100%X - IVSizeX, 0%Y, IVSizeX,IVSizeY)

and put instead
B4X:
pnlpreview.Addview(IV,25,25,pnlpreview.Width-50,pnlPreview.Height-50)
IVSizeX=IV.Width
(the "25" and "50" are due to the margins that you use in your example)

Your pnlpreview initialization must be previous to all this code.
 
Last edited:
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Yea, I figured this out already, and got it inside my panel. So far everything works. Much faster than what I was doing...
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
You know whats funny. Changing this:

B4X:
Sub SetPixelColor( x As Int, y As Int, Color As Int)

    cv.DrawCircle( dist/2 + x*dist, dist/2 + y*dist, pixelRadius, Color,True, 0)

End Sub

To this:
B4X:
Sub SetPixelColor( x As Int, y As Int, Color As Int)
    cv.DrawCircle( dist/2 + x*dist, dist/2 + y*dist, pixelRadius, Color,True, 0)
End Sub

Breaks the app, causing it to lock up. All I did was remove the whitespace!
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
You know whats funny. Changing this:

B4X:
Sub SetPixelColor( x As Int, y As Int, Color As Int)

    cv.DrawCircle( dist/2 + x*dist, dist/2 + y*dist, pixelRadius, Color,True, 0)

End Sub

To this:
B4X:
Sub SetPixelColor( x As Int, y As Int, Color As Int)
    cv.DrawCircle( dist/2 + x*dist, dist/2 + y*dist, pixelRadius, Color,True, 0)
End Sub

Breaks the app, causing it to lock up. All I did was remove the whitespace!

Well, those spaces weren't put randomly, they served a purpose :D

Seriously talking, there may be other issues or changes causing it.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Yea i know, its very odd... bugaboo somewhere.

Edit: Found the bug. B4A Debug mode, of course... I had to clean the project and now it works.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Well, I have the preview working the way I want to so far.

I guess I will take the one that I came up with, and file it under "performance testing/crysis"
 
Upvote 0
Top