2

社区,

我的问题如下:

我为我的 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.TBitmap 而不是 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出了什么问题?

4

3 回答 3

1

我似乎已经部分找到了已知尺寸图像的解决方案,这很可能是 android 的 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 平台上不是线程安全的。

于 2014-11-13T12:25:25.773 回答
0

如果您先创建位图然后再放文件:TBitmap.Create(dimensions) 然后是 LoadFromFile,它是否有效?

于 2014-11-12T15:39:12.327 回答
0

我通过将“版本信息”部分中的选项“largeHeap”从“False”更改为“True”解决了同样的问题。

之后不再出现 OutOfMemoryError。

于 2017-04-05T07:11:11.330 回答