2

I am doing following to convert TBitmap(Firemonkey) to string:

function BitmapToBase64(Bitmap: Tbitmap): string;
var
  BS: TBitmapSurface;
  AStream: TMemoryStream;
begin
  BS := TBitmapSurface.Create;
  BS.Assign(Bitmap);
  BS.SetSize(300, 200);
  AStream := TMemoryStream.Create;
  try
    TBitmapCodecManager.SaveToStream(AStream, BS, '.png');
    Result := TNetEncoding.Base64.EncodeBytesToString(AStream, AStream.Size);
  finally
    AStream.Free;
    BS.Free;
  end;
end;

How can I revert the string back to TBitmap? I did following which doesn't produce TBitmap:

procedure Base64ToBitmap(AString: String; Result : Tbitmap);
var
  ms : TMemoryStream;
  BS: TBitmapSurface;
  bytes : TBytes;
begin
  bytes := TNetEncoding.Base64.DecodeStringToBytes(AString);
  ms := TMemoryStream.Create;
  try
    ms.WriteData(bytes, Length(bytes));
    ms.Position := 0;
    BS := TBitmapSurface.Create;
    BS.SetSize(300, 200);
    try
      TBitmapCodecManager.LoadFromStream(ms, bs);
      Result.Assign(bs);
    finally
      BS.Free;
    end;
  finally
    ms.Free;
  end;
end;

I need smaller size of base64 string so that I can transmit it to Datasnap server. Normal base64 string gives me Out of memory as size of string goes greater then 200000 - 1000000 in length.

shariful
  • 455
  • 1
  • 9
  • 21

1 Answers1

4

In BitmapToBase64(), you are passing the TMemoryStream itself to TNetEncoding.Base64.EncodeBytesToString(), which does not accept a stream as input to begin with. You need to pass the value of the stream's Memory property instead:

function BitmapToBase64(Bitmap: Tbitmap): string;
var
  BS: TBitmapSurface;
  AStream: TMemoryStream;
begin
  BS := TBitmapSurface.Create;
  BS.Assign(Bitmap);
  BS.SetSize(300, 200);
  AStream := TMemoryStream.Create;
  try
    TBitmapCodecManager.SaveToStream(AStream, BS, '.png');
    Result := TNetEncoding.Base64.EncodeBytesToString(AStream.Memory, AStream.Size);
  finally
    AStream.Free;
    BS.Free;
  end;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • what about Base64ToBitmap? String is ok, now I need back to TBitmap. – shariful Jun 03 '16 at 06:32
  • @shariful offhand, I don't see anything wrong with Base64ToBitmap(), but then I'm not very familiar with working with TBitmapSurface. – Remy Lebeau Jun 03 '16 at 14:31
  • Remy, BitmapToBase64's stream size and Base64ToBitmap's stream size is not same, did you notice that? Is this case why TBitmap is not Assigned? – shariful Jun 03 '16 at 14:45
  • @shariful no, I did not notice that, because I have not run the code. Base64 is a lossless format, it decodes to the same size it encodes, so either TNetEncoding.Base64 is broken, or something else is going on. What is the actual difference in size? Did you compare the original bytes to the decoded bytes looking for differences? – Remy Lebeau Jun 03 '16 at 15:11