Convert Label to Bitmap

Omar

Member
Licensed User
Longtime User
Hello,

I have tried to convert a label to bitmap but unfortunately have made no progress with this and would appreciate if someone could kindly assist to guide me in the right direction.

Basically I have a Label1 which is modified during the execution of the application and I want to save the result of that into a bitmap if that is possible.

Thanks.
 

Yafuhenk

Active Member
Licensed User
Longtime User
This code makes a printscreen. Maybe you can use this as a first start.
You need the Reflection Library

B4X:
Sub PrtScn
   Dim Obj1, Obj2 As Reflector
    Dim bmp As Bitmap
    Dim c As Canvas
    Obj1.Target = Obj1.GetActivityBA
    Obj1.Target = Obj1.GetField("vg")
    bmp.InitializeMutable(Activity.Width, Activity.Height)
    c.Initialize2(bmp)
    Dim args(1) As Object
    Dim types(1) As String
    Obj2.Target = c
    Obj2.Target = Obj2.GetField("canvas")
    args(0) = Obj2.Target
    types(0) = "android.graphics.Canvas"
    Obj1.RunMethod4("draw", args, types) 
    Dim Out As OutputStream
    Dim t As Long
   Dim f As String
   t = DateTime.Now
   f = t
   Out = File.OpenOutput(File.DirRootExternal, f & ".png", False)
    bmp.WriteToStream(Out, 100, "PNG")
    Out.Close
   Dim n As Notification
   n.Initialize
   n.Vibrate = True
   n.Notify(1) 
   Dim ct1 As CustomToast
   ct1.Initialize
   ct1.Show("Printscreen has been saved",1000,Gravity.TOP,0,0)
   For i = 1 To 10
      DoEvents
   Next
End Sub
 
Upvote 0

Omar

Member
Licensed User
Longtime User
Thank you so much YAFUHENK and Erel.

I have been working with the reflection option overnight but it just is not working properly, now I started with Erel's option with the following code:

B4X:
   Dim c As Canvas
   Dim r As Rect
   r.Initialize(0dip, 0dip, Label1.Width, Label1.Height)
   c.DrawDrawable(Label1.Background, r)
    Dim Out As OutputStream
    Out = File.OpenOutput(File.DirInternal, "tmp.png", False)
   c.Bitmap.WriteToStream(Out, 100, "PNG")
    Out.Close

However I keep getting a Null Pointer Exception. I really appreciate your support and hope you can guide on what's wrong with this?

Thanks.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Where are you getting the null pointer exception? Try removing the dip from the rect definition, these should be absolute co-ordinates I would have thought.
 
Upvote 0

Omar

Member
Licensed User
Longtime User
Thanks stevel05.

I tried that as well when I was troubleshooting this, the error is occurring on this line:

B4X:
c.DrawDrawable(Label1.Background, r)

I appreciate your suggestions.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
You haven't initialized the Canvas object, try this:

B4X:
Dim c As Canvas
Dim r As Rect
Dim OutImg As Bitmap

OutImg.InitializeMutable(Label1.Width,Label1.Height)
r.Initialize(0, 0, Label1.Width, Label1.Height)

c.Initialize2(OutImg)
c.DrawDrawable(Label1.Background, r)

Dim Out As OutputStream
Out = File.OpenOutput(File.DirInternal, "tmp.png", False)
c.Bitmap.WriteToStream(Out, 100, "PNG")
Out.Close
 
Upvote 0

Omar

Member
Licensed User
Longtime User
Thanks very much stevel05.

I greatly appreciate your help and the code is executing now without any errors. Thanks so much.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Hi Omar,

It was bugging me why the reflection method wasn't working. Looking at the View documentation is said that 'The view must have already done a full layout before this function is called'. I tried running the method forceLayout and added doevents to give a chance to be processed, and it now appears to work.



B4X:
Sub ViewToBmp
    Dim Obj1, Obj2 As Reflector
    Dim bmp As Bitmap
    Dim c As Canvas

   Obj1.Target=Label1
   Obj1.RunMethod("forceLayout")
   DoEvents

    bmp.InitializeMutable(Label1.Width, Label1.Height)
    c.Initialize2(bmp)
    Dim args(1) As Object
    Dim types(1) As String
   
    Obj2.Target = c
    Obj2.Target = Obj2.GetField("canvas")
    args(0) = Obj2.Target
    types(0) = "android.graphics.Canvas"
    Obj1.RunMethod4("draw", args, types)
   
   Activity.SetBackgroundImage(c.Bitmap)
   
End Sub

I think this should give you what you want.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Not thinking logically:BangHead:

Label1.Invalidate does the same job as the Obj1.RunMethod("forceLayout"), you still need the DoEvents.

As a general subroutine:

B4X:
Sub ViewToBmp(ThisView As View) As Bitmap

   'Ensure the view is updated
   ThisView.Invalidate
   DoEvents

    Dim Obj1, Obj2 As Reflector
    Dim bmp As Bitmap
    Dim c As Canvas

   Obj1.Target=ThisView

    bmp.InitializeMutable(Label1.Width, Label1.Height)
    c.Initialize2(bmp)
    Dim args(1) As Object
    Dim types(1) As String
   
    Obj2.Target = c
    Obj2.Target = Obj2.GetField("canvas")
    args(0) = Obj2.Target
    types(0) = "android.graphics.Canvas"
    Obj1.RunMethod4("draw", args, types)
   
   
   Return c.Bitmap
   
End Sub

Steve
 
Last edited:
Upvote 0

Omar

Member
Licensed User
Longtime User
Thank you so much stevel05 :icon_clap:

This worked perfectly, I was really struck trying to figure out this and had almost given up hope after the DrawText method was not working either.

I am very grateful for all your help! :sign0188:


Thanks again.
 
Upvote 0
Top