如何使用Delphi XE5在IOS上保存位图图片

时间:2014-02-12 01:06:22

标签: android ios image delphi delphi-xe5

我需要,在从互联网下载图像后,我想将图像保存到用户设备(iOS或Android),这样用户就不必多次下载图像。

据我了解,在iOS上,我只能保存JPG或PNG文件格式。如何将delphi中的Bitmap文件转换为.JPG或.PNG图片文件? 我在VCL中看到支持TPNGImages,但不支持FMX。

当我使用SomeBitmap.bitmap.SaveToFile(GetHomePath+PathDelim+'Documents'+PathDelim+'Pictures'+PathDelim+PictureName+'.png';时 它没有做任何事情也没有抛出异常。 救命 ? ?

通过Delphi XE5开发iOS / Android

2 个答案:

答案 0 :(得分:2)

在给定有效的文件名和位置时,

TBitmap.SaveToFile效果非常好(至少在Android上 - 我无法与iOS通话)。但是,如果不这样做,它只是默默地失败而没有错误,大概是因为在某些移动操作系统上很难处理异常。所以实际问题是提供的文件名或位置,在这种情况下,它似乎是位置。

永远不要假设您可以猜到跨平台的文件夹位置。始终使用TPath中函数返回的其中一个文件夹。它们列在Standard RTL Path Functions across the Supported Target Platforms下的Delphi文档中;在这种情况下,您正在寻找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也是如此。两者都可在所有支持的平台上使用。 (请注意,这是SysUtils版本的ForceDirectories跨平台版,而不是FileCtrl版本,这是特定于Windows的版本。)

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设备在那里测试它,但类似的代码应该适合你(如果您指定有效的文件夹位置和文件名,如上所述)。使用XE5 Update 2在Win7 64位上进行编译和测试。

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;

答案 1 :(得分:2)

这里有各种各样的事情需要澄清:

  1. 直截了当地说,FMX源表现出极其愚蠢的异常恐惧症,尽管个别病例可以随着时间推移得到修复。 XE5中这种恐惧症的一个例子是TBitmap.SaveToFile,当给出无效输入时,它通常会无声地失败。

  2. 正如Ken White所说,你不应该假设系统定义的文件夹位于何处。也就是说,我对IOUtils并不那么热情,即使它必须被使用(除非你直接调用本机API函数)。简而言之,使用简单的PathDelim方法将是完全有效的,但IOUtils愚蠢地不尊重传统的Delphi RTL命名约定,其中XxxPath意味着'包括尾随路径分隔符';正是由于这种分歧,TPath.Combine开始发挥作用。

  3. 您明显假设FMX TBitmap与VCL类一样,保存为BMP格式不正确 - 默认情况下会保存到PNG。