【问题标题】:DecodeBase64 and EncodeBase64 behaves differently in Delphi 10.2 and 10.3DecodeBase64 和 EncodeBase64 在 Delphi 10.2 和 10.3 中的行为不同
【发布时间】:2020-05-27 01:20:45
【问题描述】:

我有以下 2 个程序:

  1. Flex 服务器(Delphi 10.2 程序,作为接受 POST 和 GET API 调用的服务运行)

  2. FireMonkey 中的移动应用程序(Delphi 10.3 多设备应用程序,可同时构建到 Android 和 iOS)

有以下要求:

  • 通过 API 调用从移动应用程序将图像发布到 flex 服务器。

我使用过 Delphi 的 Soap.EncdDecdSystem.NetEncoding 库。

当前进程:

将移动应用上的TImage位图转换为内存流,并转换为base64字符串。将图像作为字符串发布到弹性服务器。在弹性服务器上,根据Soap.EncdDecd 中的base64 解码方法将字符串解码回内存流。

在移动应用上,我将图像转换为 Base64 字符串,然后通过 API 调用发送。

代码如下所示:

Var FImage: TMemoryStream;
sImageBlob : String 

FAttachedImage.SaveToStream(FImage); // FAttachedImage is a TImage
sImageBlob  := EncodeBase64(FImage.Memory,  FImage.Size)

而在flex服务器中,我使用decode方法将其解码回来并保存到DB中:

Var Serverimage: TMemoryStream;
Serverimage  := TBytesStream.Create(DecodeBase64(sImageBlob  ))

问题:

由于 flex 服务器是 10.2 版,它会将其解码回 AnsiString,即使我使用相同的库 (Soap.EncdDecd),它也会将其编码为 string,从而导致无法取回正确的图像。

在我看来,主要问题在于Soap.EncdDecd 内部有两个Delphi 版本。在 Delphi 10.2 中,它将字符串解码为 AnsiString,而 FireMonkey (Delphi 10.3) 将图像内存流编码为字符串。 Delphi 10.2 flex 服务器如何处理我通过使用 JavaScript 库编码为 base64 的 Web 应用程序发送的字符串。

有人可以帮我解决这个问题,或者提供另一种方法来通过 API 调用将图像作为字符串传递吗?并将其转换回 API 服务器中的内存流。

【问题讨论】:

  • 你为什么还要使用base64?不必通过 HTTP/REST 发送二进制数据
  • Base64 将大小增加 33%。你应该尽可能避免它。
  • @RemyLebeau,首先 Base64 编码是由另一个开发人员在我之前在 flex 服务器(这是一个 HTTP/REST API 服务器)上实现的。它适用于 HTML/JavaScript、React 和 React-Native Web 应用程序发出的 API 调用,这些应用程序将图像作为 Base 64 编码字符串传递(在那些通过 JavaScript 编码库编码的应用程序上)。因此删除该编码部分网络方法将是重大变化,我必须更改和测试所有其他应用程序。因此,为什么我添加了问题“或提供另一种方法来通过 API 调用将图像作为字符串传递?”
  • 我期待在 Fire monkey 移动应用程序中将 TMemoryStream 或 Timage 转换为字符串,然后在 Flex 服务器中执行相反的操作。从而为这些 FireMonkey 应用程序创建了一个观看图像保存方法。

标签: delphi image-processing firemonkey


【解决方案1】:

找到了解决办法,如下:

来自 firemonkey 应用:

var
  AnAttachment: TMemoryStream;
  lMemoria: TMemoryStream;
  lStrEnv: TStringStream;
  AJSONObject : TJSONObject

 // 
 AJSONObject  := TJSONObject.Create;
 
 AnAttachment.ImageBlob.Position := 0;
 lStrEnv := TStringStream.Create;
 TNetEncoding.Base64.Encode(AnAttachment, lStrEnv);

 AJSONObject.AddPair('ImageBlob', lStrEnv.DataString);

// 来自flex服务器端 使用 Soap.EncdDecd;

 var 
 JSON: TJSONObject;

 //sJSONString is the JSON String that comes via the API call 
 JSON := TJSONObject.ParseJSONValue(sJSONString) as TJSONObject;

 AnAttachment: TMemoryStream;

 AnAttachment :=  TMemoryStream.Create;

 AnAttachment  := TBytesStream.Create(DecodeBase64(JSON.GetValue('ImageBlob').ToJSON));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 2019-10-18
    • 2012-02-25
    • 1970-01-01
    • 2017-10-13
    相关资源
    最近更新 更多