Android Question OutOfMemory Error with FitCenterBitmap

Ferdari

Active Member
Licensed User
Hi everyone, im having this error on some low-end devices, i load a list of 30 webp images fille from a For, the list generates very well on medium and high-end but bad on low-end with code OutOfMemory Error:

B4X:
java.lang.OutOfMemoryError:
  at android.graphics.Bitmap.nativeCreate (Native Method)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:1266)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:1219)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:1169)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:1130)
  at anywheresoftware.b4a.objects.drawable.CanvasWrapper.Initialize (CanvasWrapper.java:81)
  at stickers.memetflix.utils._v5 (utils.java:33)
  at stickers.memetflix.pack._vvvvvvvvvvvvvv2 (pack.java:483)
  at stickers.memetflix.pack._activity_create (pack.java:372)
  at java.lang.reflect.Method.invoke (Native Method)
  at anywheresoftware.b4a.BA.raiseEvent2 (BA.java:196)
  at stickers.memetflix.pack.afterFirstLayout (pack.java:104)
  at stickers.memetflix.pack.access$000 (pack.java:17)
  at stickers.memetflix.pack$WaitForLayout.run (pack.java:82)
  at android.os.Handler.handleCallback (Handler.java:907)
  at android.os.Handler.dispatchMessage (Handler.java:105)
  at android.os.Looper.loop (Looper.java:216)
  at android.app.ActivityThread.main (ActivityThread.java:7625)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:524)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:987)

Im using the @klaus sub FitCenterBitmap but i think need some optimization, don't know if the canvas consumes high memory or the LoadBitmapSample

B4X:
Sub FitCenterBitmap(Imv As ImageView, Dir As String, FileName As String)
 
    Private bmp As Bitmap = LoadBitmapSample(Dir, FileName, 32dip,32dip)'LoadBitmapResize(Dir, FileName, 35dip,35dip ,True)
    Private cvs As Canvas
    cvs.Initialize(Imv)
 
    Dim rectDest As Rect
    Dim delta As Int
    If bmp.Width / bmp.Height > Imv.Width / Imv.Height Then
        delta = (Imv.Height - bmp.Height / bmp.Width * Imv.Width) / 2
        rectDest.Initialize(0, delta,Imv.Width, Imv.Height - delta)
    Else
        delta = (Imv.Width - bmp.Width / bmp.Height * Imv.Height) / 2
        rectDest.Initialize(delta, 0, Imv.Width - delta, Imv.Height)
    End If
    cvs.DrawBitmap(bmp, Null, rectDest)
    Imv.Invalidate
 
    Dim jo = bmp As JavaObject
    jo.RunMethod("recycle", Null)
 
End Sub
My pictures are 512x512px resized dynamically to 32x32dip then added to the a Scrollview in a grid of 3 items per row, max 30 images, i also added to manifest the:
B4X:
SetApplicationAttribute(android:largeHeap,"true")
but still experiencing the problem on some devices.


Capture+_2019-12-02-21-52-45_resized_FrogResizer100%.jpg

Your help will be apreciated.
 
Last edited:

Ferdari

Active Member
Licensed User
Why is the canvas needed here?

Why aren't you using LoadBitmapResize?

Example of showing a list with thousands of images: https://www.b4x.com/android/forum/t...-imageviews-and-many-rows.101431/#post-636920
Thanks Erel, what do you think its the best way to fit height - centered with image proportion

i tried this:

B4X:
 LoadBitmapResize(Dir, FileName, 32dip,32dip ,True)
with gravity.Center but it doesn't fit the height, it only appears centered inside the ImageView(rectangle), but small image, sorry i feel very new working with imageviews.
 

Ferdari

Active Member
Licensed User
Can you upload the images?
Im triying the LoadBitmapResize(Dir, FileName, Width,Height,True) But with exact Imageview size + gravity.center, it works ok and fill perfect the imageview without distortion, will check the next hours if fixes the OutOfMemory Error and no user reports.

Changed my code to:
B4X:
Sub FitCenterBitmap(Imv As ImageView, Dir As String, FileName As String, Width As Int, Height As Int)
    Imv.Bitmap=LoadBitmapResize(Dir, FileName, Width, Height ,True)
    Imv.Gravity=Gravity.CENTER 'Bit.Or(Gravity.CENTER_HORIZONTAL, Gravity.fill)
End Sub
Testing on my device feels more faster and fluid than using canvas.

Ill report back the results :)
 

LucaMs

Expert
Licensed User
Why aren't you using LoadBitmapResize?
Changed my code to:
B4X:
Sub FitCenterBitmap(Imv As ImageView, Dir As String, FileName As String, Width As Int, Height As Int)
    Imv.Bitmap=LoadBitmapResize(Dir, FileName, Width, Height ,True)
    Imv.Gravity=Gravity.CENTER 'Bit.Or(Gravity.CENTER_HORIZONTAL, Gravity.fill)
End Sub
You don't need FitCenterBitmap (which was a great Klaus's method he wrote when LoadBitmapResize didn't exist).
This is what Erel meant.
B4X:
    Imv.Bitmap=LoadBitmapResize(Dir, FileName, Width, Height ,True)
    Imv.Gravity=Gravity.CENTER
are enough, of course.
 
Top