【问题标题】:How to save bitmap pictures on IOS using Delphi XE5如何使用Delphi XE5在IOS上保存位图图片
【发布时间】:2014-02-12 01:06:21
【问题描述】:

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

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

当我使用SomeBitmap.bitmap.SaveToFile(GetHomePath+PathDelim+'Documents'+PathDelim+'Pictures'+PathDelim+PictureName+'.png'; 它不做任何事情,也不抛出异常。 帮助 ? ?

通过 Delphi XE5 为 iOS/Android 开发

【问题讨论】:

    标签: android ios image delphi delphi-xe5


    【解决方案1】:

    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 也将创建它们;两者都可在所有支持的平台上使用。 (请注意,跨平台的是ForceDirectoriesSysUtils 版本,而不是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;
    

    【讨论】:

    • 转成png或jpeg的问题怎么办?这是怎么做到的?
    • 我可以从 Chris 的回答中看出这一点,但在你的回答中没有说出来。
    • @Jordan:我用ForceDirectories 段落(就在第二个TPath.Combine 示例之后)进行了说明。
    • 哦,我忽略了这一点。它在清晨。非常感谢,感谢您总是回答并帮助我解决我提出的所有问题!
    • 您好,forums.embarcadero.com/thread.jspa?messageID=639090&#639090 上有一个非常相似的问题未解决
    【解决方案2】:

    这里有很多事情需要澄清:

    1. 坦率地说,FMX 源表现出极其愚蠢的异常恐惧症,尽管个别情况会随着时间的推移而得到修复。 XE5 中这​​种恐惧症的一个例子是TBitmap.SaveToFile,当输入无效时,它通常会静默失败。

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

    3. 您认为 FMX TBitmap 与 VCL 类一样,保存为 BMP 格式的明显假设是不正确的 - 它默认保存为 PNG。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-30
    • 2014-06-09
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    相关资源
    最近更新 更多