Android Question Snapshot of Grid

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I have a grid class that scrolls horz and vert, of course only parts of it are on the screen at one time.

Is there anyway of getting a complete snapshot of the grid? Getting what is not displayed on the screen?

Using the "Getting a Screenshot Programmatically" I can get a snapshot of what is currently on the screen.

Is there anyway getting the whole virtual screen?

Would prefer to not have to scroll the screen and take multiple snapshots. Is there a way to loop the views and make a big bitmap?

Forgot to say that my Grid class consists of the following:
B4X:
    Private mGrid_Main_Panel                 As Panel
        Private mGrid_FixedColumns_Panel     As Panel
        Private mGrid_FixedHeader_HSV        As HorizontalScrollView
        Private mGrid_FixedColumns_VSV       As ScrollView
        Private mGrid_Body_SV2D              As ScrollView2D


BobVal
 
Last edited:

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I cannot see how that will work.

The first part is the same as the "getting a screenshot programmatically"

The second part is just drawing it to the ImageView. on his panel

There is nothing there that captures the parts of the screen that are not showing

Example of what I am talking about. I have a Golf Score card on the screen. On my device only the first 7 holes show without scrolling to the left
and only two players show without scrolling down. I want to be able to create a file for the user of the whole score card.

Thanks BobVal
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I looked at the differences.

"Getting a Screenshot Programmatically" makes a copy of the Activity and saves the image to a file.

"Capture Complete Panel to imageview" creates a copy of a panel and copy it into an ImageView.

You must check whether the panel can be bigger than the screen.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User


Yes, it can.

You can use:
B4X:
Sub SavePanelImage(pnlToSave As Panel)
  ' Take a screenshot.
  Dim Obj1, Obj2 As Reflector
  Dim bmp As Bitmap
  Dim c As Canvas
  Dim now, i As Long
  Dim dt As String
  DateTime.DateFormat = "yyMMddHHmmss"
  now = DateTime.now
  dt = DateTime.Date(now) ' e.g.: "110812150355" is Aug.12, 2011, 3:03:55 p.m.
  Obj1.Target = Obj1.GetActivityBA
  Obj1.Target = Obj1.GetField("vg")
  bmp.InitializeMutable(pnlToSave.Width, pnlToSave.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
  Out = File.OpenOutput(File.DirRootExternal, dt & ".png", False)
  bmp.WriteToStream(Out, 100, "PNG")
  Out.Close
    Log(File.DirRootExternal & "/" & dt & ".png")
End Sub

Few changes.

You should add Directory and File name as parameters and modify... etc.
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
Please stop.

I JUST tried it, it just does the same thing.

You aren't getting the big picture. My Grid panel is only part of the size of the Activity screen, but it contains a HorizontalScrollView, ScrollView and a ScrollView2D.
Now they contain the rest of the image that is not being show on the panel unless they are scrolled.

Something needs to loop the Scrollviews to show there data. In a sense scroll the window so the data comes into view then copy it.

Capture Complete Panel is only taking the Physical panel.

Because I have already tried the code and it does not work for me. Why don't you make a panel with a scrollview in it that has more data then will show on the screen and try it. You will see that it only takes a snapshot of the actual panel and not the "lets call it" virtual panel
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
Fine, just explain to me how I pass all these Views

B4X:
    Private mGrid_Main_Panel                 As Panel
        Private mGrid_FixedColumns_Panel     As Panel
        Private mGrid_FixedHeader_HSV        As HorizontalScrollView
        Private mGrid_FixedColumns_VSV       As ScrollView
        Private mGrid_Body_SV2D              As ScrollView2D

and get 1 big bitmap? The represents the whole grid?


So I guess the answer is. I need to change the savepanelimage to return a bitmap instead of writing it to a file and then I have to figure out how to splice the different bitmaps together to form one large image.
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
You can simpy pass, for example, mGrid_FixedColumns_VSV.Panel,
but you would get only the content of that panel, of course.

The only solution that comes to mind, unfortunately, if you want to get a big picture that contains all, you should create a very big panel, with the same elements fully visible, set its left > 100%x so that the panel is not visible and then save its contents (passing that "invisible" panel).
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
Also the Sub SavePanelImage(pnlToSave As Panel) you posted above does not work properly.

It makes a Bitmap the size of the panel but when drawing the canvas to the bitmap start at the top of the activity.
In my case only grabbing the top half of the panel.
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
So you thing the answer should be to make a huge panel to display the grid in?

Sorry, I just do not like it, will look for another way.
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
Well from parts of someone else's code (nicholas.jj.taylor - http://www.b4x.com/android/forum/threads/getsubbitmap.30747/) I was able to figure out what I needed to do

I have 4 main parts from the Grid.
B4X:
        Private mGrid_FixedColumns_Panel     As Panel
        Private mGrid_FixedHeader_HSV        As HorizontalScrollView
        Private mGrid_FixedColumns_VSV       As ScrollView
        Private mGrid_Body_SV2D              As ScrollView2D

From each type I need to set different Width or Heights

B4X:
GetBitmapFromPanel(mGrid.GridFixedColumnsPanel, True)
GetBitmapFromHorizontalScrollView(mGrid.GridFixedHeaderHSV, true)
GetBitmapFromScrollView(mGrid.GridFixedColumnsSV, true)
GetBitmapFromScrollView2D(mGrid.GridBody, true)

Now I have 4 Bitmaps the represent the Grid. Fixed Side Bitmap (Panel) Fixed Header Bitmap (HorizontalScrollView), Fixed Side Bitmap (ScrollView) and Body (ScrollView2D).
All I have to do now is splice them together into one bitmap - which I did manually using a graphic editor and is Grid.png below

B4X:
Sub GetBitmapFromPanel(ScrSource As Panel, WriteToFile As Boolean) As Bitmap
    Dim StrMethod As String = "Sub GetBitmapFromPanel(ScrSource As Panel) As Bitmap"
    Dim IntWidth  As Int = ScrSource.Width
	Dim IntHeight As Int = ScrSource.Height
	
    Return GetBitmapFromView(IntWidth, IntHeight, ScrSource, WriteToFile)
End Sub

Sub GetBitmapFromScrollView2D(ScrSource As ScrollView2D, WriteToFile As Boolean) As Bitmap
    Dim StrMethod As String = "Sub GetBitmapFromScrollView2D(ScrSource As ScrollView2D) As Bitmap"
    Dim IntWidth  As Int = ScrSource.Panel.Width
	Dim IntHeight As Int = ScrSource.Panel.Height
	
    Return GetBitmapFromView(IntWidth, IntHeight, ScrSource, WriteToFile)
End Sub

Sub GetBitmapFromHorizontalScrollView(ScrSource As HorizontalScrollView, WriteToFile As Boolean) As Bitmap
    Dim StrMethod As String = "Sub GetBitmapFromHorizontalScrollView(ScrSource As HorizontalScrollView) As Bitmap"
    Dim IntWidth  As Int = ScrSource.Panel.Width
	Dim IntHeight As Int = ScrSource.Height
	
    Return GetBitmapFromView(IntWidth, IntHeight, ScrSource, WriteToFile)
End Sub

Sub GetBitmapFromScrollView(ScrSource As ScrollView, WriteToFile As Boolean) As Bitmap
    Dim StrMethod As String = "Sub GetBitmapFromScrollView(ScrSource As ScrollView) As Bitmap"
    Dim IntWidth  As Int = ScrSource.Width
	Dim IntHeight As Int = ScrSource.Panel.Height
	
    Return GetBitmapFromView(IntWidth, IntHeight, ScrSource, WriteToFile)
End Sub

Sub GetBitmapFromView(IntWidth As Int, IntHeight As Int, ScrSource As View, WriteToFile As Boolean) As Bitmap
   Dim StrMethod As String = "Sub GetBitmapFromView(IntWidth as Int, IntHeight as Int, ScrSource As View) As Bitmap"
   Dim BmpResult As Bitmap = Null
   
   Try            
      Dim Bmp As Bitmap
      Bmp.InitializeMutable(IntWidth, IntHeight)
      
      Dim Cnv As Canvas
      Cnv.Initialize2(Bmp)
      
      Dim Rfl As Reflector
      Rfl.Target = Cnv
      
      Dim AryObjectRef(1) As Object 
      AryObjectRef = Array As Object (Rfl.GetField("canvas"))
      
      Dim AryObjectTypeRef(1) As String
      AryObjectTypeRef = Array As String ("android.graphics.Canvas")
      
      Dim RftView As Reflector
      RftView.Target = ScrSource
      
      RftView.RunMethod4("draw", AryObjectRef, AryObjectTypeRef)
      
      BmpResult = Bmp   

      If WriteToFile Then
         Dim now     As Long	  
         Dim dt      As String
		 
         DateTime.DateFormat = "yyMMddHHmmss"
		 
         now = DateTime.now
         dt = DateTime.Date(now) ' e.g.: "110812150355" is Aug.12, 2011, 3:03:55 p.m.
		 
         Dim Out As OutputStream
  
         Out = File.OpenOutput(File.DirRootExternal, cDatabase.DatabasePath(False) &dt & ".png", False)

         Bmp.WriteToStream(Out, 100, "PNG")
         Out.Close
      End If	  
   Catch
      'CdException.Show(StrClass, StrMethod, LastException)
   End Try
   
   Return BmpResult
End Sub

WOW, so there it is. Now I have all the parts I will be back and I have a routine that puts them all together.

BobVal



PS: I will turn the above routines into a BitmapFromView that will handle all the different types of Object Views passed to it. Just need to get everything working first.
 

Attachments

  • SideHeader.png
    3.1 KB · Views: 273
  • Header.png
    6.8 KB · Views: 229
  • Side.png
    20.1 KB · Views: 237
  • Body.png
    69.1 KB · Views: 245
  • Grid.png
    96.5 KB · Views: 248
Last edited:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…