OutOfMemoryError and bitmap

adamioan

Member
Licensed User
Longtime User
Greetings to all and happy new year.
I have an issue developing an application. I have an activity with a scroll view which contains some pictures (100 pcs).
After compiling and testing, I lived the OutOfMemoryError exception, while changing the orientation. After some research in the online community I decided to apply the one bitmap solution. I dimmed and initialized bmpBitmap in the Sub Globals section and in the sub that fills the scroll with images, I did draw on that bitmap and set it as background to a label.
Using the same bitmap in all labels, without re-initialize it, had the side-effect of updating the previous declared labels with the new background. If I initialize the bitmap in the loop, I will be trapped in the OutOfMemory error again.
Can someone help?
Below is a sample code of filling the labels with backgrounds and I have attach two shots of the application. First-one is the wrong result and the second if the preferred.
B4X:
Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   Dim cnvCanvas As Canvas 
   Dim rctRect As Rect 
   Dim bmpBitmap As Bitmap 
End Sub

' Fill the movie scroll with Icons
Sub FillMovies_Icons(ScreenWidth As Int)
Dim Cursor1 As Cursor 
Dim Query As String 
Dim M, N, Gap, SemiGap As Int
Dim ImageLeft, ImageTop, ImageWidth, ImageHeight, RankValueWidth As Int 

   ' Building SQL
   bla bla bla

   ' Query database
   bla bla bla

   ' Initialize Drawables
   bmpBitmap.InitializeMutable(ImageWidth, ImageHeight)
   cnvCanvas.Initialize2(bmpBitmap)
   
   ' Loop in records
   For N=0 To Cursor1.RowCount - 1
      Cursor1.Position=N

      Dim lblMovieIcon As Panel 
      Dim lblTitle As Label
      
      ' Label Poster
      lblMovieIcon.Initialize("MovieItem")
      svMovies.Panel.AddView(lblMovieIcon, ImageLeft, ImageTop, ImageWidth, ImageHeight)
      
      ' Title
      lblTitle.Initialize("")
      lblMovieIcon.AddView(lblTitle, SemiGap, SemiGap, ImageWidth - Gap, 10)
      lblTitle.TextColor=Colors.White 
      lblTitle.Gravity=Gravity.TOP + Gravity.CENTER_HORIZONTAL 
      lblMenu.TextSize=MM.Settings_FontSize 
      MM.WrapLabelHeight(lblTitle, False)
      MM.ShowEllipsis_Label(lblTitle, Field_name)
      
      ' Shadow
      For M=0 To SemiGap
         cnvCanvas.DrawLine(SemiGap - M, SemiGap - M, ImageWidth - SemiGap + M, SemiGap - M, Colors.ARGB(150 - (150 * M / SemiGap), 0, 0, 0), 1)
         cnvCanvas.DrawLine(SemiGap - M, SemiGap - M, SemiGap - M, ImageHeight - SemiGap + M, Colors.ARGB(150 - (150 * M / SemiGap), 0, 0, 0), 1)
         cnvCanvas.DrawLine(SemiGap - M, ImageHeight - SemiGap + M, ImageWidth - SemiGap + M + 1, ImageHeight - SemiGap + M, Colors.ARGB(150 - (150 * M / SemiGap), 0, 0, 0), 1)
         cnvCanvas.DrawLine(ImageWidth - SemiGap + M, ImageHeight - SemiGap + M, ImageWidth - SemiGap + M, SemiGap - M, Colors.ARGB(150 - (150 * M / SemiGap), 0, 0, 0), 1)
      Next
      
      ' Poster bitmap
      rctRect.Initialize(SemiGap, SemiGap, ImageWidth - SemiGap, ImageHeight - SemiGap)
      If File.Exists(MM.OutputFolder & "/posters", Field_id & ".jpg") Then 
         cnvCanvas.DrawBitmap(LoadBitmapSample(MM.OutputFolder & "/posters", Field_id & ".jpg", ImageWidth - SemiGap, ImageHeight - SemiGap), Null, rctRect)
      Else
         cnvCanvas.DrawBitmap(MM.bmpNoImage, Null, rctRect)
      End If
      
      ' Title gradient
      For M=0 To 10
         cnvCanvas.DrawLine(SemiGap - 1, SemiGap + lblTitle.Height * M/7, ImageWidth - SemiGap, SemiGap + lblTitle.Height * M/7, Colors.ARGB(250 - M * 24, 0, 0, 0), lblTitle.Height/7)
      Next
      
      ' Draw bmpBitmap
      lblMovieIcon.SetBackgroundImage(cnvCanvas.Bitmap)
      lblMovieIcon.Invalidate 
   Next
   
   ' Close DB
   MM.sqlDB.Close 
End Sub
 

Attachments

  • ????? ?????.jpg
    ????? ?????.jpg
    66.9 KB · Views: 318

Erel

B4X founder
Staff member
Licensed User
Longtime User
I don't think that I understand your code. You cannot use the same bitmap with different views (unless you want the image to be the same).

You can use code similar to this code to only load the bitmaps once:
B4X:
'Activity module
Sub Process_Globals
   Dim Images As List
End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
      LoadImages
   End If
   'add the ImageViews and assign the bitmaps from the list
   For Each bmp As Bitmap In Images
      Dim iv As ImageView
      iv.Initialize(...)
      ...
   Next
End Sub

Sub LoadImages
   Images.Initialize
   'for each image in ...
      Dim bmp As Bitmap = LoadBitmapSample(...)
      Images.Add(bmp)
   'next
End Sub
 
Upvote 0

adamioan

Member
Licensed User
Longtime User
Hi Erel, thanks for your reply.
The problem is that if I load all the images I get OutOfMemory errror. In another post I saw that the solution is to use only one bitmap and put it on the canvas of each view. The result is the first picture in attachment.
If I use lblPoster.setBackgroundImage(loadbitmap ... ) I will get the exception.
I am sure that this will have the same result with the image list.
I 'll try it right now
 
Upvote 0

adamioan

Member
Licensed User
Longtime User
Hi Erel,
I tried your suggestion but without success. I am still getting OutOfMemoryError.
I have a code module, so I dimmed there lstPosterFilename and lstPosterBitmap. I filled these two lists in a previous activity so they can be accessed from all activities.
In the activity that I need to display them, I use a scroll view and create a label for each poster. I need to add some graphics in the label's image (like shadow, a small star image and some text) so I use a canvas which targeting to label.
Do you thing this approach is correct? Do you have something else to suggest?
I will send you my code to have a look.

EDIT:
I finally got it working, without all effects. I managed to find a solution without using Canvas. Canvas is starving for memory :D
I used a label with a shadow blur and change all the drawable elements to label.
Just a question for you, which is the lighter view that can host an image?
label, panel or image view?

Thank you in advance
 
Last edited:
Upvote 0
Top