Adam
Adam

Reputation: 21

Delphi XE7 Firemonkey - Creating a TBitmap form file throws EJNIException java.lang.OutOfMemoryError

Community,

my problem is the following:

I have written a XE7 FMX application for my Kindle Fire where I want to work with TBitmaps. The problem is, I'm unable to create a TBitmap from the storage of my device. If I run the application as a Win32-app on my computer all works, but if I run it as an android-app, it throws the exception from the title.

Here is my code:

procedure TForm1.Button1Click(Sender: TObject);
var
  MyImage: TBitmap;
  Path: String;
begin
  Path := TPath.GetDocumentsPath + TPath.DirectorySeparatorChar + 'test.png';
  if TFile.Exists(path, true) then
  begin
    MyImage := TBitmap.CreateFromFile(path);        //<- Here it fails
  end;
end;

This code has no sense but this is only a test program. If this works I can use it in my main program but it already fails at this point. (And I have already checked that he used the FMX.Graphics.TBitmap and not the VCL)

Here is my stack:

System._DbgExcNotify(86,0x11fc0b0,0x5bf3b0dd,0x11fc0b0,0x5bf3b0dd)
System.NotifyReRaise(0x11fc0b0,0x5bf3b0dd)
System._RaiseAtExcept(0x11fc0b0,0x5bf3b0dd)
System._RaiseExcept(0x11fc0b0)
System.Internal.Excutils.DoRaiseJNIExceptionCallBack('class java.lang.OutOfMemoryError','java.lang.OutOfMemoryError')
Androidapi.Jni.HandleJNIException(0xbe42f8)
Androidapi.Jnimarshal.ExecJNI(0x5d226490,0x125e998)
:5C8B8A14 DispatchToImport
:5C8C4FA8 dispatch_first_stage_intercept
Fmx.Graphics.Android.TBitmapCodecAndroid.LoadFromFile(0x127e7f8,'/data/data/com.embarcadero.Project1/files/test.png',0x1297040,4096)
Fmx.Graphics.TBitmapCodecManager.LoadFromFile(0x5cbab65c,'/data/data/com.embarcadero.Project1/files/test.png',0x1297040,4096)
Fmx.Graphics.TBitmap.LoadFromFile(0x127e788,'/data/data/com.embarcadero.Project1/files/test.png')
Fmx.Graphics.TBitmap.TBitmap(0x127e788,1,'/data/data/com.embarcadero.Project1/files/test.png')
Unit1.TForm1.Button1Click(0xad1c48,0x103dbd8)
[...] rest is unneccessary

Where is the error? Is it my fault or did delphi something wrong?

Upvotes: 2

Views: 3490

Answers (3)

Dennis Rusch
Dennis Rusch

Reputation: 1

I solved the same issue by changing the option "largeHeap" in the "Version Info" section from "False" into "True".

No more OutOfMemoryError after that.

Upvotes: 0

3ChordMonty
3ChordMonty

Reputation: 11

I seemed to have partly found a solution for images with known dimensions, this could very well be a delphi XE6/XE7 bug with android as it works with IOS and Win32/64?

My App worked with Min-SDK 10 set, as i changed it to sdk 15 or higher, i kept getting the same error as above, and in XE7, an exception string "Bitmap too large." If I specified the dimensions at exactly the file dimensions, it would work, yet dynamically if i loaded the png and it was a different size (smaller or bigger) would get "Bitmap too large." With SDK 10 it seems I could create a bitmap with no dimensions, if you try with no dimensions 15 > it doesn't load.

This works with any sized image file as long as you know the exact dimensions of the file:

 bmpscale:=1024;
try
    tb := TBitmap.Create(bmpscale,bmpscale);
    tb.LoadFromFile('img.png');
finally
    freeandnil(tb)
end;

Edit: After much testing and research (and weeping), I have found 2 things which have solved my problem.

tb:=TBitmap.CreateFromFile('img.png');

This creates the bitmap according to the size of the file. The second solution which seems to be the main problem is the fact I was trying to create and load the bitmap from within a thread. To solve I put the load into a thread queue or synchronize

TThread.queue(nil,
 procedure
      begin
          tb:=TBitmap.CreateFromFile('img.png');
      end);

I imagine the TBitmap library is not thread safe on the android platform.

Upvotes: 1

lechonex
lechonex

Reputation: 1

Does it work if you create the bitmap first and loaf the file afterwards: TBitmap.Create(dimensions) and then LoadFromFile?

Upvotes: 0

Related Questions