社区,
我的问题如下:
我已经为我的Kindle Fire编写了一个XE7 FMX应用程序,我想在那里使用TBitmaps。问题是,我无法从设备的存储中创建TBitmap。如果我在电脑上以Win32应用程序的形式运行该应用程序,一切都可以,但如果我以android应用程序的方式运行,它会从标题中抛出异常。
这是我的代码:
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;
这段代码毫无意义,但这只是一个测试程序。如果这有效,我可以在我的主程序中使用它,但它在这一点上已经失败了。(我已经检查过他使用的是FMX.Graphics.Bitmap,而不是VCL)
这是我的堆栈:
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
错误在哪里?是我的错还是德尔菲做错了什么?
我似乎已经为已知尺寸的图像找到了部分解决方案,这很可能是安卓系统中的delphi XE6/XE7错误,因为它可以与IOS和Win32/64一起工作?
我的应用程序使用Min SDK 10集,当我将其更改为SDK 15或更高版本时,我一直收到与上面相同的错误,在XE7中,出现了一个异常字符串"位图太大"。如果我指定的尺寸与文件尺寸完全相同,它会起作用,但动态地,如果我加载了png,并且它是不同的尺寸(更小或更大),则会得到"位图太小"使用SDK 10,我似乎可以创建一个没有维度的位图,如果你尝试没有维度15>,它不会加载。
这适用于任何大小的图像文件,只要你知道文件的确切尺寸:
bmpscale:=1024;
try
tb := TBitmap.Create(bmpscale,bmpscale);
tb.LoadFromFile('img.png');
finally
freeandnil(tb)
end;
编辑:经过大量的测试和研究(哭泣),我发现了两件事解决了我的问题。
tb:=TBitmap.CreateFromFile('img.png');
这将根据文件的大小创建位图。第二个似乎是主要问题的解决方案是,我试图从线程中创建和加载位图。为了解决这个问题,我将负载放入线程队列或同步
TThread.queue(nil,
procedure
begin
tb:=TBitmap.CreateFromFile('img.png');
end);
我想TBitmap库在android平台上不是线程安全的。
如果先创建位图,然后遍历文件:TBitmap.create(dimensions),然后LoadFromFile,效果会好吗?
我通过将"版本信息"部分的选项"largeHeap"从"False"更改为"True"解决了同样的问题。
之后不再出现内存不足错误。