Search code examples
delphiimage-processingfiremonkey

DecodeBase64 and EncodeBase64 behaves differently in Delphi 10.2 and 10.3


I have following 2 programs:

  1. A flex server (Delphi 10.2 program that runs as a service that accepts POST and GET API calls)

  2. A mobile app in FireMonkey (Delphi 10.3 multi-device app that gets build to both Android and iOS)

Have the following requirement:

  • POST an image via an API call from the mobile app to the flex server.

I have used Delphi's Soap.EncdDecd and System.NetEncoding libraries.

Current process:

Convert the TImage bitmap on the mobile app to a memory stream and convert it to a base64 string. POST the image to the flex server as a string. On the flex server, decode the string back to a memory stream based on base64 decode method in Soap.EncdDecd.

On the mobile app, I convert the image to a Base64 string before sending it via the API call.

The code looks something like follows:

Var FImage: TMemoryStream;
sImageBlob : String 

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

And in the flex server, I use the decode method to decode it back and save it to the DB:

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

Problem:

Since the flex server is version 10.2, it decode it back to AnsiString where the mobile app even though if I use the same library (Soap.EncdDecd) it encode it to a string, resulting on a failure to retrieve the correct image back.

The main problem, as I see it, is inside Soap.EncdDecd have two Delphi versions. In Delphi 10.2, it decodes the string to an AnsiString and FireMonkey (Delphi 10.3) encode the image memory stream to a string. How ever the Delphi 10.2 flex server works fine with strings that I have sent via web apps which use JavaScript libraries to encode to base64.

Can someone please help me with this problem, or provide ANOTHER way to pass an image as a string through an API call? And convert it back to a memory stream in the API server.


Solution

  • Found a solution and it is as follows :

    From the firemonkey app :

    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);
    

    // From the flex server end uses 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));