Jump to content
KimHJ

Unable to save from TImage to file

Recommended Posts

I have this code where I send an jpg image with TidTCPClient to a TidTCPServer.

On the Server side the image aperea in a TImage, but no file is created when I save it. I tried using .jpg as well I try to use the MemoryStream.SaveToFile.

I look in many forums and it looks like the do the same thing, what is wrong with this code?

Here is the server code.

procedure TMainForm.IdTCPServer1Execute(AContext: TIdContext);
var
  JSON: TJSONObject;
  StringStream: TStringStream;
  MemoryStream: TMemoryStream;
begin
  MemoryStream := nil;
  StringStream := nil;
  JSON := nil;
  try
    StringStream := TStringStream.Create('', TEncoding.ASCII);
    AContext.Connection.IOHandler.LargeStream := True;
    AContext.Connection.IOHandler.ReadStream(StringStream, SizeOf(StringStream), True);
    JSON := TJSONObject.ParseJSONValue(StringStream.DataString) as TJSONObject;
    MemoryStream := TMemoryStream.Create;
    IdDecoderMIME1.DecodeStream(JSON.GetValue('image_encoded').Value, MemoryStream);
    TThread.Synchronize(nil,
      procedure
      begin
        Edit2.Text := '';
        Edit2.Text := JSON.GetValue('message').Value;
        Image1.Bitmap.LoadFromStream(MemoryStream);
      end);
  finally
    MemoryStream.Free;
    StringStream.Free;
    JSON.Free;
  end;
   SaveImageToDisk;
end;

procedure TMainForm.SaveImageToDisk;
var
 CsFilename: String;
begin
        CsFilename :=  Edit2.Text + '.png';
        Image1.Bitmap.SaveToFile(CsFilename);
end;

 

Share this post


Link to post
SizeOf(StringStream)

This is wrong. This is the size of a pointer. How many bytes are you expecting the client to send? What does the client code look like? Ideally, the client should send the JSON's size before sending the JSON's data, and then the server should read the size before the data. IOHandler.Write(TStream) and IOHandler.ReadStream() can handle that for you, but not the way you are currently using IOHandler.ReadStream(). The client can call IOHandler.Write(TStream) with AWriteByteCount=True, and the server can call IOHandler.ReadStream() with AByteCount=-1 and AReadUntilDisconnect=False.

 

That being said, since JSON is textual data, I would suggest using IOHandler.ReadString() instead of IOHandler.ReadStream(). Also, the preferred encoding for JSON is UTF-8 not ASCII.

IdDecoderMIME1.DecodeStream(JSON.GetValue('image_encoded').Value, MemoryStream);
...
Image1.Bitmap.LoadFromStream(MemoryStream);

You are not rewinding the TMemoryStream back to position 0 before loading it. So the TImage ends up blank before you save it to file.

 

Edited by Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×