B4J Code Snippet Create PNG File for Map Markers

I needed a method to create .png files "on the fly" - to be used as custom map markers in my AB Material app.
Normally, this data is exposed when hovering over the current map marker - but I wanted to show this info for every marker shown, as an additional marker along side...

Borrowing from many examples found on this forum, I managed this.

These files are just temporary in the app, and are periodically cleaned out (deleted).

The B4XMainPage Class file...
Sub Class_Globals
    Private mCanvas As Canvas
    Private fx As JFX
    Type TextMetric (Width As Double,Height As Double)
End Sub

Public Sub Initialize

End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Dim rand As Int = Rnd(1,5000)
    Dim t As String = " Spd: "&rand&"  Time: "&DateTime.Time(DateTime.Now)&" Truck #: ( "&(rand+376)&" )"
    Dim ret As String = Makelabel(t,rand) 
    Log(" File created: "&ret)

End Sub

Sub Makelabel(t As String, rand As Int) As String
    Dim fs As Double = 16
    Dim TM As TextMetric = MeasureText(t,fx.DefaultFont( fs))

    Log(" Height: "&TM.Height & "   Width: " & TM.Width)

    Dim width, height As Double
    width = TM.Width + 6
    height = TM.Height + 1
    mCanvas.DrawRect( 0  , 0,  width, height,  fx.Colors.White,  True,  1) 'check size
    mCanvas.DrawText2(t,   1, 16 ,fx.DefaultFont(fs),fx.Colors.Black,"LEFT",TM.Width)
    Dim fn As String = rand&"_"&DateTime.Now
    Dim Dir As String
    Dir = File.DirApp&"\tmplbl"
    Dim Out As OutputStream
    Out = File.OpenOutput(Dir, fn&".png", False)
    Return fn&".png"
End Sub

Sub MeasureText(Text As String,TFont As Font) As TextMetric
    Dim TB,Bounds As JavaObject
    Dim TM As TextMetric

    Bounds = TB.RunMethodJO("create",Null).RunMethodJO("text",Array(Text)).RunMethodJO("font",Array(TFont)).RunMethodJO("build",Null).RunMethodJO("getLayoutBounds",Null)

    TM.Width = Bounds.RunMethod("getWidth",Null)
    TM.Height = Bounds.RunMethod("getHeight",Null)
    Return TM
End Sub

New Project attached: mkpng.zip


  • MakePNGLabel.zip
    6.4 KB · Views: 150
  • mkpng.zip
    1.5 KB · Views: 148
Last edited:


Licensed User
Longtime User
Included in the first post is the actual "Make PNG" project that I use in my ABM app.

It is simple to use, just create a map with the "key" as the file name (png) and the "value" as the text to display on the image, and pass the map file name as a parameter to the jar called with shell.

Another complex "map of maps" is used to display these markers from within the ABM app - (showlbl_clicked method).

Runs very quickly and produces my desired results...

The overall code is very simplistic. It was the many hours of experimenting / refactoring to make it work that was difficult.
However, B4X makes it so much easier than all the other alternatives...

         Dim mapname As String = rand&"_map.map"
        File.WriteMap( File.DirApp&"/www/"&ABMShared.AppName&"/images/tmplbl",  mapname,  mamap )
        Dim shl As Shell
        shl.Initialize("shl", "java.exe",     Array As String("-cp", "mkpng.jar", "b4j.example.main", mapname))
        shl.WorkingDirectory = File.DirApp
        shl.Run(10000) 'set a timeout of 10 seconds
        Wait For shl_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
        If Success And ExitCode = 0 Then
            Log("Success creating png's ")
            Log("Error: " & StdErr)
        End If

        showlbl_clicked("")  ' show images on the Google Map...

Show / Hide these image markers...
Sub showlbl_clicked(target As String)

    Dim sloc1 As ABMSwitch = page.NavigationBar.ExtraContent.Component("showlbl")
    Dim b As Boolean = sloc1.State

    If b Then
        For Each key As String In markmap.Keys
            Dim kval As Map = markmap.Get(key)
            Dim fname As String = kval.Get("fname")
            Dim latt As Double = kval.Get("lt")
            Dim lont As Double = kval.Get("ln")
            Dim path As String
            ' info label...
            If File.Exists(File.DirApp&"/www/"&ABMShared.AppName&"/images/tmplbl", fname) Then
                path = "../images/tmplbl/"&fname
                gm1.AddMarkerEx( fname ,   latt,  lont+0.0007, " " ,  " ", path,  False )
                Log(" Marker File not found: "&kval)
            End If
    ' hide extra markers
        For Each key As String In markmap.Keys
    End If
End Sub

Result: (speed and time for each primary marker)

Last edited: