Send Image from Android to Datasnap Restful Server
Question
I have an Android app that send data back to a datasnap server using the RESTFul client stuff in XE2.
I have it working fine for sending standard basic data, but part of the app includes storing images the user takes.
I initially tried to use TStream, but that never got back to the server - it just seemed to hang. My current thought is to convert the byte[] of the image to a base64 string and reconvert at the datasnap end.
To convert the image to a base64 string at the Android end, I do the following:
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, stream);
String encodedString = Base64.encode(stream.toByteArray)
encodedString
then gets sent as a standard Delphi string
at the server end the code to decode is
function Base64Decode(const EncodedText: string): TBytes;
var
DecodedStm: TBytesStream;
Decoder: TIdDecoderMIME;
begin
Decoder := TIdDecoderMIME.Create(nil);
try
DecodedStm := TBytesStream.Create;
try
Decoder.DecodeBegin(DecodedStm);
Decoder.Decode(EncodedText);
Decoder.DecodeEnd;
Result := DecodedStm.Bytes;
SetLength(Result, DecodedStm.Size); // add this line
finally
DecodedStm.Free;
end;
finally
Decoder.Free;
end;
end;
then
var
Bytes : TBytes;
image : TJPEGImage;
stream : TBytesStream;
begin
Bytes := Base64Decode(Photo);
stream := TBytesStream.Create(Bytes);
image := TJPegImage.Create;
image.LoadFromStream(stream);
This creates an error in the loadFromStream
method, basically the jpeg is corrupted. I'm guessing there is something wrong with either then encoding (unlikely), or converting to a delphi string then decoding to a byte[] (likely).
So this is a long winded way to ask if anyone has any suggestions on how to send an image from an Android app to a DataSnap server in Delphi XE2?
Solution
uses
DBXJSONCommon,
function TServerImageMethods.ConvertJPEGToJSon(pFilePath: string): TJSONArray;
var
AFileStream: TFileStream;
begin
AFileStream := TFileStream.Create(pFilePath, fmOpenRead);
Result := TDBXJSONTools.StreamToJSON(AFileStream, 0, AFileStream.Size);
end;
I convert back to a TStream with:
AFileStream := TDBXJSONTools.JSONToStream(JSONArray);
PS.: You can compress the stream with ZLIB for best performance.
OTHER TIPS
I'm loading JPEG images, but I set the pointer at the beginning, and configure the image:
stream.Seek(0,soFromBeginning);
image.PixelFormat := jf24Bit;
image.Scale := jsFullSize;
image.GrayScale := False;
image.Performance := jpBestQuality;
image.ProgressiveDisplay := True;
image.ProgressiveEncoding := True;
image.LoadFromStream(stream);
If stream.size > 0 then
// OK
else
// not OK
I'll also try decoding an ANSIString, to check if it is related to the Unicode change.