Android Question [Solved or rather explained] Screenshot bitmap larger than screen??

mark35at

Well-Known Member
Licensed User
I generate a full screen (in activity properties) map (OSMdroid) and make a screenshot. The screenshot is saved to a png file. Then I start a new activity and create an imageview with height 100%y and width 100%x. I load the png file into a bitmap and assign it to the imageview. There is no problem with any of the code.

The problem is that in the subsequent imageview, the bitmap appears to be zoomed. Only a small portion is visible in the middle.

This only happens on my smartphone (resolution 1280 x 720, 320 dpi), on my 10" tablet (1280 x 752, 160 dpi) everything is okay. The bitmap has resolution 1280 x 670 on the smartphone, according to ES Explorer.

The solution is to use:

B4X:
iv.Gravity=gravity.FILL
but I would still like to know why. Am I missing something? Thanks for any help.
 

mark35at

Well-Known Member
Licensed User
Didn't think to do that. I thought the 1280 x 670 reported by ES Explorer would be correct. Will check.
 

mark35at

Well-Known Member
Licensed User
loaded the file into an imageview and checked bitmap height and width, it shows 1280 x 672!

The solution is gravity.fill but I don't understand why a screenshot taken on a device and loaded on the same device should have a different size???

Will try and make a screenshot from the device tonight.
 

mark35at

Well-Known Member
Licensed User
Using the emulator, I created a small project to show what I mean. I have reduced the pictures by 50% to upload them here.

The project code (without gravity.fill) is below.

The Bitmap info from log:
Height: 670, width: 1280


Main:
B4X:
#Region  Project Attributes
    #ApplicationLabel: Screenshot
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: landscape
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: True
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim TileSource As String="MapquestOSM"                                        'Mapnik, OSMPublicTransport, MapquestOSM
    Dim dt As String="Maptemp"                                                            'Filename for screenshot
    Dim Timer1 As Timer                                                                    'Used to create a delay
  
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 MapView1 As MapView
    Dim MapCenter As GeoPoint
    Dim TouchEventsOverlay1 As TouchEventsOverlay                                        'Allows click & long click events
    Dim SimpleLocationOverlay1 As SimpleLocationOverlay
    Dim MarkersOverlay1 As MarkersOverlay  
  
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")
    Activity.AddMenuItem("Take Screenshot", "MnuShot")
  
    Timer1.Initialize( "Timer1",500)
  
    '   pass an EventName when initializing the MapView
       '   MapView has two events: CenterChanged and ZoomChanged
    MapView1.Initialize("MapView1")
    Activity.AddView(MapView1, 0, 0, 100%x, 100%y)
  
    MapView1.SetMultiTouchEnabled(True)
    MapView1.SetZoomEnabled(True)
    MapCenter.Initialize(47.3763900,15.0911300)    'Leoben as center
  
    MapView1.Zoom=15
    MapView1.SetCenter(47.3763900,15.0911300)
    MapView1.SetTileSource(TileSource)
    Activity.Title="OSMDroid ["&MapView1.Zoom&"]"
      
    'initialize the SimpleLocationOverlay and add it to the MapView
       SimpleLocationOverlay1.Initialize(MapView1)
       MapView1.AddOverlay(SimpleLocationOverlay1)
      
      'set the SimpleLocationOverlay to display it's icon at the map center
      SimpleLocationOverlay1.SetMyLocation3(MapView1.GetCenter)
  
    'initialize the MarkersOverlay and add it to the MapView
       'an EventName is required as we will listen for the two events that MarkersOverlay generates
    MarkersOverlay1.Initialize(MapView1, "") 'No events
    MapView1.AddOverlay(MarkersOverlay1)
     
    'Add touch events to map
    TouchEventsOverlay1.Initialize("TouchEventsOverlay1")
    MapView1.AddOverlay(TouchEventsOverlay1)
          
    Timer1.Enabled=True    'Wait for a short period for map to finish drawing
  
End Sub

Sub Timer1_Tick
    'Need the timer to let the map finish drawing
  
    Timer1.Enabled=False
      
End Sub

Sub MnuShot_Click
    TakeScreenShot
End Sub

Sub TakeScreenShot
    ' Take a screenshot.
    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
    Out = File.OpenOutput(File.DirRootExternal, dt & ".png", False)
    bmp.WriteToStream(Out, 100, "PNG")
    Out.Close
  
    StartActivity(ShowScreen)
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
ShowScreen:
B4X:
#Region  Activity Attributes
    #FullScreen: True
    #IncludeTitle: True
#End Region

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 b As Bitmap
    Dim iv As ImageView
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")
    'Load screenshot into imageview
    iv.Initialize("")
    Activity.AddView(iv,0,0,100%x,100%Y)
    b.Initialize(File.DirRootExternal,Main.dt & ".png")
    iv.Bitmap=b
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 

Attachments

mark35at

Well-Known Member
Licensed User
Added to ShowScreen after loading bitmap:

B4X:
Log("Bitmap Height: " & b.Height & ", width: " & b.Width)
    Log("Activity Height: " & Activity.Height & ", width: " & Activity.Width)
Log reports:

Bitmap Height: 670, width: 1280
Activity Height: 670, width: 1280
 

mark35at

Well-Known Member
Licensed User
Here is the data from my smartphone LG P880

Bitmap Height: 640, width: 1280
Activity Height: 640, width: 1280
Device Layout Values: 1280 x 720, scale = 2.0 (320 dpi)
 

Erel

Administrator
Staff member
Licensed User
These are the expected resolutions. The bitmap size is the same as the activity size. Now the bitmap density is set to 1. This is why you see a larger bitmap. You have two options:
- Load the bitmap with LoadBitmapSample and Gravity.Fill
- Use AcceleratedSurface library that allows you to load the bitmap and set the density.
 

mark35at

Well-Known Member
Licensed User
Thanks Erel, I am already using your first solution. I just wanted to understand why as in windows, a screenshot is only as big as the screen.
 
Top