Recent

Author Topic: Base64  (Read 1055 times)

mpknap

  • New member
  • *
  • Posts: 35
Base64
« on: June 13, 2018, 06:57:29 am »
How to decode the Base 64 format? Below file content. And the other way, how to encode a JPG file (20x20 pix) to the same format?

 
Code: Pascal  [Select]
  1. {"detections": [{"frame_content": "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAAAAAA7VNdtAAACv0lEQVRIDVXBMVbrMBRAwfue5O8YQxYEHUVKejg07L+HJBLyv40KZuIZVbSiE9rRhhaUqKGG4hlVtKIT2tGGFpSooYbiGVW0ohPa0YYWlKihhuIZVbSiE9rRhhaUqKGG4hlVtKIT2tGGFpSooYbiBe3ohDb0gCoqqKAf1FG8oB2d0IYeUEUFFfSDOooXtKMT2tADqqiggn5QR/GCdnRCG3pAFRVU0A/qKF7Qjk5oQw+oooIK+kEdxSt6QhtaUUWJkqmjhuIVPaENraiiRMnUUUPxip7QhlZUUaJk6qiheEVPaEMrqihRMnXUULyiJ7ShFVWUKJk6aigu6Iw2tPDHggYaqKG4oDPa0MIfCxpooIbigs5oQwt/LGiggRqKCzqjDS38saCBBmooLuiMNrTwx4IGGqihuKAz2lFBgQJV1NEvGigu6Ix2VFCgQBV19IsGigs6ox0VFChQRR39ooHigs5oRwUFClRRR79ooLigM9pRQYECVdTRLxoo3tAj+ocKKiiZOmroG8UbekT/UEEFJVNHDX2jeEOP6B8qqKBk6qihbxRv6BH9QwUVlEwdNfSN4g09on+ooIKSqaOGvlF8oIoqCpQoUaA7uqIbig9UUUWBEiUKdEdXdEPxgSqqKFCiRIHu6IpuKD5QRRUFSpQo0B1d0Q3FB6qookCJEgW6oyu6oXhHK0oUKFCggRq6o47iHa0oUaBAgQZq6I46ine0okSBAgUaqKE76ije0YoSBQoUaKCG7qijeEcrShQoUKCBGrqjjuITJUqUKNGBBhrohjqKT5QoUaJEBxpooBvqKD5RokSJEh1ooIFuqKP4RIkSJUp0oIEGuqGO4hMlSpQo0YEGGuiGOoovpgMVpsHU0BUdKL6YDlSYBlNDV3Sg+GI6UGEaTA1d0YHii+lAhWkwNXRFB4ovpgMVpsHU0BUd6D8pRLGV1zBGtwAAAABJRU5ErkJggg=='", "timestamp": "1528481412762", "latitude": "51.708491", "longitude": "19.476362", "altitude": "12", "accuracy": "1", "provider": "google map", "width": "680", "height": "460", "id": "1"}], "device_id": "raspberry", "androidVersion": "none", "device_model": "zero", "app_version": "1", "system_version": "raspbian", "device_type": "raspberry"}



After encoding JPG file I have to send it to the server using the JSON method.

GetMem

  • Hero Member
  • *****
  • Posts: 3330
Re: Base64
« Reply #1 on: June 13, 2018, 07:25:24 am »
First of all the encoded image is a png not jpg. It's kinda annoying when you expect a jpg and it turns out to be something different. Use the following two methods to convert Base64 to stream and vice versa(as in the attached project):
Code: Pascal  [Select]
  1. uses base64;
  2.  
  3. function StreamToBase64(const AStream: TMemoryStream; out Base64: String): Boolean;
  4. var
  5.   Str: String;
  6. begin
  7.   Result := False;
  8.   if AStream.Size = 0 then
  9.     Exit;
  10.   AStream.Position := 0;
  11.   try
  12.     SetLength(Str, AStream.Size div SizeOf(Char));
  13.     AStream.ReadBuffer(Pointer(Str)^, AStream.Size div SizeOf(Char));
  14.     Base64 := EncodeStringBase64(Str);
  15.     Result := Length(Base64) > 0;
  16.   except
  17.     on E: Exception do
  18.       ShowMessage(E.Message);
  19.   end;
  20. end;
  21.  
  22. function Base64ToStream(const ABase64: String; var AStream: TMemoryStream): Boolean;
  23. var
  24.   Str: String;
  25. begin
  26.   Result := False;
  27.   if Length(Trim(ABase64)) = 0 then
  28.     Exit;
  29.   try
  30.     Str := DecodeStringBase64(ABase64);
  31.     AStream.Write(Pointer(Str)^, Length(Str) div SizeOf(Char));
  32.     AStream.Position := 0;
  33.     Result := AStream.Size > 0;
  34.   except
  35.     on E: Exception do
  36.       ShowMessage(E.Message);
  37.   end;
  38. end;

PS: I implemented the former one, you should do the Image->Stream->Base64 conversion.

User137

  • Hero Member
  • *****
  • Posts: 1767
    • Nxpascal home
Re: Base64
« Reply #2 on: June 14, 2018, 03:38:10 am »
Code: Pascal  [Select]
  1. AStream.ReadBuffer(Pointer(Str)^, AStream.Size div SizeOf(Char));
That's odd. Shouldn't you be referring to the location of data in the string, and are there char sizes different than 1? So simplified:
Code: Pascal  [Select]
  1. AStream.ReadBuffer(Str[1], AStream.Size);

edit: Testing things... Pointer(Str)^ seems equal to Str[1]. But SizeOf(Char) is 1, whereas SizeOf(WideChar) is 2. SizeOf(Str[1]) is 1 for string type, but 2 for widestring.
« Last Edit: June 14, 2018, 04:04:45 am by User137 »

ASerge

  • Hero Member
  • *****
  • Posts: 1029
Re: Base64
« Reply #3 on: June 14, 2018, 06:52:33 pm »
Code: Pascal  [Select]
  1. AStream.ReadBuffer(Pointer(Str)^, AStream.Size div SizeOf(Char));
That's odd. Shouldn't you be referring to the location of data in the string, and are there char sizes different than 1? So simplified:
Code: Pascal  [Select]
  1. AStream.ReadBuffer(Str[1], AStream.Size);
edit: Testing things... Pointer(Str)^ seems equal to Str[1]. But SizeOf(Char) is 1, whereas SizeOf(WideChar) is 2. SizeOf(Str[1]) is 1 for string type, but 2 for widestring.
No. ReadBuffer(Pointer(Str)^,... is better than ReadBuffer(Str[1]... In second case compiler add code to ensure string is unique and add range check.
SizeOf(Char) is compatible with compiler where Char is WideChar (last Delphi, for example).