Android Question ImageView and bitmap issue

alwaysbusy

Expert
Licensed User
Longtime User
Hi,

I'm having trouble with loading a created bitmap in an imageview (see screenshot).

When I load a bitmap I created in B4A the size is wrong (top imageview). However, when I send it through a dummy function where I create a new bitmap with exectly the same dimensions, it works correctly (bottom imageview).

Here is the dummy function (an example project is added as an attachement)
B4X:
Sub Dummy(b As Bitmap) As Bitmap
    Dim c As Canvas
    Dim b2 As Bitmap
    b2.InitializeMutable(b.Width, b.Height)
    c.Initialize2(b2)
    Dim D As Rect
    D.Initialize(0,0,b2.Width, b2.Height)
    c.DrawBitmap(b, Null, D)
    Return b2
End Sub

I would like to avoid doing this because I have to load a lot of bitmaps in my app.
 

Attachments

  • screenshot.png
    26.1 KB · Views: 231
  • BitmapIssue.zip
    13.1 KB · Views: 171

Informatix

Expert
Licensed User
Longtime User
Load your bitmaps with LoadScaledBitmap from my Accelerated Surface library and all your problems will be gone.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It seems like a density issue. What is the purpose of this code? To create a new image file or to resize the image?

If you want to resize the image then you can use this code and it will work correctly:
B4X:
  ' make the image
   Dim bmp As Bitmap = CreateScaledBitmap(LoadBitmap(File.DirAssets, "settings.png"), 10%x, 10%x)
   
   iv1.Bitmap = bmp
End Sub

Sub CreateScaledBitmap(bmp As Bitmap, Width As Int, Height As Int) As Bitmap
   Dim d As Rect
   Dim xBuildPicture As Bitmap
   xBuildPicture.InitializeMutable(Width, Height)
   Dim xBuildCanvas As Canvas
   xBuildCanvas.Initialize2(xBuildPicture)
   d.Initialize(0,0,Width, Height)
   xBuildCanvas.drawBitmap(bmp, Null, d)
   Return xBuildPicture
End Sub
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
Hi Informatix,

I'm aware of your excellent lib, but if possible, I would like to avoid an additional lib. It would be nice if I could understand why it is wrong in native B4A. Additionally, it is saved in the correct dimensions so rescaling is not needed. A simple LoadBitmap() shoud return the correct bitmap. The source bitmap is e.g 110x110. After LoadBitmap() it is also 110x110, but something must have changed. Redrawing (not rescaling) it on a new 110x110 bitmap fixes it again.

Cheers,

Alain
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
Hi Erel,

I know I'm doing some weird programming In my app I work with skins that do need some heavy drawing. So when the app starts for the first time it creates all the needed bitmaps, backgrounds etc ONCE. The next time the app is started a loadbitmap() would just have to look in the saved cache folder without a need to make all the heavy calculations again.

Alain
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Size of the Accelerated Surface library: 30 Ko. That won't make a difference in your app.
I agree with Erel, it's probably a problem with density.
EDIT: And LoadScaledBitmap does not rescale the bitmap if you don't want to.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Here is the explanation. When you set a bitmap with a size of 100x100 to an ImageView the ImageView compares the image scale (1.0) to the device scale (2.0 for example) and scales the image.

In order to exactly fit the image in this case you need an ImageView with a size of 200x200.

Usually you just set the Gravity to Gravity.Fill. However if you want to create exact images and save them then you can use this code:
B4X:
Sub CreateScaledBitmap(bmp As Bitmap, Width As Int, Height As Int)
   Width = Width / (100dip / 100) '100dip / 100 = device scale
   Height = Height / (100dip / 100)
   Dim D As Rect
   Dim xBuildPicture As Bitmap
   xBuildPicture.InitializeMutable(Width, Height)
   Dim xBuildCanvas As Canvas
   xBuildCanvas.Initialize2(xBuildPicture)
   D.Initialize(0,0,Width, Height)
   xBuildCanvas.drawBitmap(bmp, Null, D)
   Dim out As OutputStream
   out = File.OpenOutput(File.DirRootExternal, "bitmap.png", False)
   xBuildPicture.WriteToStream(out,100, "PNG")
   out.Close
End Sub
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
No, not yet. Seems I may have to abandon my idea anyway because the quality of the pictures is not as good as when I create them at run time. I just came up with this idea because I'm using huge amounts of memory when I create all my pictures. I must have some kind of memory leak when I do something like this in a timer loop. I'm having trouble getting back the memory:

B4X:
QRPanel.Initialize("QRPanel")
Activity.AddView(QRPanel, 0%x, 0%x, 100%x, 100%y)
mem.LogMemory("QRPanel added " & CurrTime, False) <--------------- result is 50,1MB
       
Dim DrawTimerCanvas As Canvas
DrawTimerCanvas.initialize(QRPanel)
mem.LogMemory("QRPanel canvas initialized " & CurrTime, False) <--------------- result is 59,3MB

Anyway, I got some options from you guys, so back to the drawing table Thanks for the tips!
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…