TBitmap.SaveToFile 在提供有效文件名和位置时运行良好(至少在 Android 上 - 我无法与 iOS 对话)。但是,如果您不这样做,它只会默默地失败而不会出错,大概是因为在某些移动操作系统上很难处理异常。所以实际的问题在于提供的文件名或位置,在这种情况下,它看起来就是位置。
永远不要假设您可以跨平台猜测文件夹位置。始终使用TPath 中的函数返回的文件夹之一。它们在 Delphi 文档中的Standard RTL Path Functions across the Supported Target Platforms 下列出;在这种情况下,您正在寻找TPath.GetPicturesPath,它在Android 上返回类似'/storage/emulated/0/Pictures' 的内容。 (根据文档,iOS 设备上目前没有可访问的图片目录,尽管模拟器上似乎有。这可能是 iOS 本身的限制;您必须检查 Apple iOS 文档以确定, 但是。iOS 上的适当位置似乎在 TPath.GetDocumentsPath 返回的位置,根据 XE5 文档,该位置类似于 '/var/mobile/Applications/<application ID>/Documents'。)
其次,永远不要手动连接路径的各个部分。使用TPath.Combine(来自IOUtils 单元),如果需要,它将自动在适当的位置添加路径分隔符。如果需要,您可以链接多个调用以获取所需级别的子文件夹:
为了可读性/可维护性(iOS 位置演示):
Dest := TPath.Combine(TPath.GetDocumentsPath, 'mydir');
Dest := TPath.Combine(Dest, 'tests');
或(为简洁起见):
Dest := TPath.Combine(TPath.Combine(TPath.GetDocumentsPath, 'mydir'), 'tests');
如果您需要创建文件夹,TDirectory.CreateDirectory 将创建它们,SysUtils.ForceDirectories 也将创建它们;两者都可在所有支持的平台上使用。 (请注意,跨平台的是ForceDirectories 的SysUtils 版本,而不是Windows 特定的FileCtrl 版本。)
if not TDirectory.Exists(Dest, False) then
TDirectory.CreateDirectory(Dest);
// or
// SysUtils.ForceDirectories(Dest);
就文件格式而言,FMX.Graphics.TBitmap(通过TBitmapCodecManager 类)跨所有支持的平台提供对以下格式的支持:
JPEG (.jpeg, .jpg)
TIFF (.tiff, .tif)
GIF
PNG
BMP
这是在 Windows 上从位图转换为 .png 的示例;我没有可以在那里测试它的 Android 设备,但类似的代码应该适合您(前提是您指定了有效的文件夹位置和文件名,如上所述)。在Win7 64位上编译测试,使用XE5 Update 2。
procedure TForm1.FormShow(Sender: TObject);
var
BmpIn, BmpOut: TBitmap;
SaveParams: TBitmapCodecSaveParams;
begin
BmpIn := TBitmap.Create;
try
BmpIn.LoadFromFile('E:\TempFiles\ScreenCaps\CheckBoxChecked.bmp');
BmpOut := TBitmap.Create;
try
BmpOut.Assign(BmpIn);
SaveParams.Quality := 100;
BmpOut.SaveToFile('E:\TempFiles\ScreenCaps\CheckBoxChecked.png', @SaveParams);
finally
BmpOut.Free;
end;
finally
BmpIn.Free;
end;
end;