Android Code Snippet Capture complete Panel to imageview

Status
Not open for further replies.

ilan

Expert
Licensed User
Hi guys

i made a little code with lot of help from LucaMs (Thanks LucaMs :))

Subname: Panel Capture
Description: in this code you can capture a Panel with all his views to a imageview without saving the image and load again
Dependencies: Reflection Lib v2.40
Tags: Panel capture

B4X:
Sub Button1_Click
    'capture panel to imageview
      PanelCapture(Panel1,cardb2)
End Sub

'Capture Panel to imageview
Sub PanelCapture(pnl As Panel, Img2 As ImageView)

Dim Obj1, Obj2 As Reflector
Dim bmp As Bitmap
Dim c As Canvas
Obj1.Target = Obj1.GetActivityBA
Obj1.Target = Obj1.GetField("vg")
bmp.InitializeMutable(pnl.left + pnl.Width, pnl.Top + pnl.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)

'draw from image to canavas
Dim canvas1 As Canvas
canvas1.Initialize(Img2)
Dim scrt As Rect
scrt.Initialize(pnl.left, pnl.top, pnl.left + pnl.Width, pnl.Top + pnl.Height)
Dim rectPanel1 As Rect
rectPanel1.Initialize(0, 0,Img2.Width, Img2.Height)
canvas1.DrawBitmap(bmp, scrt , rectPanel1)
Img2.Invalidate

End Sub
 
Last edited:

Beja

Expert
Licensed User
Hi and thanks for sharing this.
Usually people capture the screen shot to use it offline, on the web or in another App, so what's the use for putting a screenshot on a view in the same app that can not be accessed to make use of it?
BTW: could you put the code in a small project, because I couldn't run it in my test project, thanks in advance.
 

ilan

Expert
Licensed User
the use of it is simple

i have a imageview and i have a panel now the change that are happening in the panel i would like to show it in a small preview box (imageview)
with this code i just copy the whole happening in the panel (and not whole screen) to a imageview (small preview)

it can be used i many different ways, think about it :)
 
Last edited:

Beja

Expert
Licensed User
Thank you.. that's cool..
The code snippet is can also be used in different ways.
 

stevel05

Expert
Licensed User
Hi Ilan, thanks for sharing. Just one point. By running the 'draw' routine on the ViewGroup you are getting a capture of the whole screen. you can run 'draw' directly on a panel (assigned to a javaobject) to get just the panel.

I am just doing this for another project, so here's what I got.

B4X:
'Draw the whole screen
Sub DrawScreen
    Dim PnlJO As JavaObject = ViewGroup
    PnlJO.RunMethod("draw",Array As Object(Cnv))
End Sub
'Draw a Panel
Sub DrawPanel(PnlJO As JavaObject)
    PnlJO.RunMethod("draw",Array As Object(Cnv))
End Sub
'Draw a view i.e. edittext or label
Sub DrawView(ViewJO As JavaObject)
    ViewJO.RunMethod("draw",Array As Object(Cnv))
End Sub
'Get the ViewGroup for the screen
Private Sub ViewGroup As JavaObject
    Dim R As Reflector
    R.Target = R.GetActivityBA
    Return R.GetField("vg")
End Sub
 

Said

Member
Licensed User
I have problem.

I used this code but getting different result than expected. Here little explanation;

I am using tabhost and panel inside this tabhost (tab 1). My panel size ise 680x898 (real pixel size, checked in windows also)

When i try to capture panel, it captures whole tabhost with same size (680x898). But because tabhost headers, i am getting truncated shot from right and bottom. It captures true size but wrong rectangle.

Am i doing wrong ? Or using tabhost control causes conflict ?

I tried to save image file to SD Card and checked. Result same. Pixel sizes ok, but different rectangle.

Regards,

-Said

ps: I just see steve's note. But because i am new on Basic4A/Java, i dont know how to fix problem.
 
  • Like
Reactions: GIS

ilan

Expert
Licensed User
hi said, you need to calculate the position of the panel to the position of tab1

B4X:
Dim scrt As Rect

scrt.Initialize(pnl.left, pnl.top, pnl.left + pnl.Width, pnl.Top + pnl.Height)
if your panel is in position top 10dip and left 10dip then add this like this

scrt.Initialize(pnl.left+10dip, pnl.top+10dip, pnl.left + pnl.Width+10dip, pnl.Top + pnl.Height+10dip)

you need to play a little bit with it if it wont work, try like this see result and if not working try like this

scrt.Initialize(pnl.left+10dip, pnl.top+10dip, pnl.left + pnl.Width , pnl.Top + pnl.Height )


hope it will work for you but what i think you need to do is to calculate the position of the panel incl. the left of the tab because i am using only a panel...
 

Rick Harris

Well-Known Member
Licensed User
Hi guys

i made a little code with lot of help from LucaMs (Thanks LucaMs :))

Subname: Panel Capture
Description: in this code you can capture a Panel with all his views to a imageview without saving the image and load again
Dependencies: Reflection Lib v2.40
Tags: Panel capture

B4X:
Sub Button1_Click
    'capture panel to imageview
      PanelCapture(Panel1,cardb2)
End Sub
 
'Capture Panel to imageview
Sub PanelCapture(pnl As Panel, Img2 As ImageView)
 
Dim Obj1, Obj2 As Reflector
Dim bmp As Bitmap
Dim c As Canvas
Obj1.Target = Obj1.GetActivityBA
Obj1.Target = Obj1.GetField("vg")
bmp.InitializeMutable(pnl.left + pnl.Width, pnl.Top + pnl.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)
 
'draw from image to canavas
Dim canvas1 As Canvas
canvas1.Initialize(Img2)
Dim scrt As Rect
scrt.Initialize(pnl.left, pnl.top, pnl.left + pnl.Width, pnl.Top + pnl.Height)
Dim rectPanel1 As Rect
rectPanel1.Initialize(0, 0,Img2.Width, Img2.Height)
canvas1.DrawBitmap(bmp, scrt , rectPanel1)
Img2.Invalidate
 
End Sub
Isn't there a way to do this without having to create such a large bitmap? This routine would work much faster if the Panel offset (left and top) would not have to be added to the width and height of the bitmap, especially if the desired capture area is very small. The problem apparently is that this code cannot take the offset of the panel into account but in stead needs to always start from the top lef corner of the screen (in the original code the full width and height is used in bmp.initialise...).
 

Mashiane

Expert
Licensed User
Hi Ilan, thanks for sharing. Just one point. By running the 'draw' routine on the ViewGroup you are getting a capture of the whole screen. you can run 'draw' directly on a panel (assigned to a javaobject) to get just the panel.

I am just doing this for another project, so here's what I got.

B4X:
'Draw the whole screen
Sub DrawScreen
    Dim PnlJO As JavaObject = ViewGroup
    PnlJO.RunMethod("draw",Array As Object(Cnv))
End Sub
'Draw a Panel
Sub DrawPanel(PnlJO As JavaObject)
    PnlJO.RunMethod("draw",Array As Object(Cnv))
End Sub
'Draw a view i.e. edittext or label
Sub DrawView(ViewJO As JavaObject)
    ViewJO.RunMethod("draw",Array As Object(Cnv))
End Sub
'Get the ViewGroup for the screen
Private Sub ViewGroup As JavaObject
    Dim R As Reflector
    R.Target = R.GetActivityBA
    Return R.GetField("vg")
End Sub
This looks interesting, I'd like to draw the contents of a label and save them as an image, can you guide me with your methods here please. Thanks.
 
Status
Not open for further replies.
Top