4

I'm using Delphi 10.1 Berlin

I want to send image data as TBytes to a Rest service using TRestRequest, but I could not find a way to pass a TBytes to the TRestRequest.AddBody() method, or any other method.

POST http://myserver:1111//Openxxx/RecxxxLxxxPxxxx HTTP/1.1
Content-Type: text/json
Host: myserver:1111
Content-Length: 28892
Expect: 100-continue
Connection: Keep-Alive

[255,216,255,224,0,16,74,70,73,70,0,1,1,0,0,1,0,1,0,0,255,219,0,132,0,9,
...
...
...
130,130,252,168,127,164,63,164,41,109,204,245,62,106,51,135,12,146,63,255,217]
2

2 Answers 2

6

TRESTRequest.AddBody() has an overload that accepts a TStream as input. You can wrap your TBytes into a TStream using the TBytesStream class.

procedure TForm1.Button1Click(Sender: TObject);
var
  ABytes: TBytes;
  AStream: TBytesStream;
begin
  ABytes := ...;
  try
    AStream := TBytesStream.Create(ABytes);
    RESTRequest1.AddBody(AStream, ctIMAGE_JPEG); 
    RESTRequest1.Execute;
  finally
    AStream.Free;
  end;
end;

Alternatively, use TRESTRequestParameterList.AddItem instead, which has an overload for TBytes:

procedure TForm1.Button1Click(Sender: TObject);
var
  ABytes: TBytes;
begin
  ABytes := ...
  RESTRequest1.Params.AddItem('body', ABytes, pkGETorPOST, [poDoNotEncode], ctIMAGE_JPEG);
  RESTRequest1.Execute;
end;

That being said, I find TRESTClient to be overly complex and buggy/limiting. More times than not, Indy's TIdHTTP is easier to use, eg:

procedure TForm1.Button1Click(Sender: TObject);
var
  ABytes: TBytes;
  AStream: TBytesStream;
begin
  ABytes := ...;
  try
    AStream := TBytesStream.Create(ABytes);
    IdHTTP1.Request.ContentType := 'image/jpeg';
    IdHTTP1.Post('http://myserver:1111//Openxxx/RecxxxLxxxPxxxx', AStream);
  finally
    AStream.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  IdHTTP1.Request.ContentType := 'image/jpeg';
  IdHTTP1.Post('http://myserver:1111//Openxxx/RecxxxLxxxPxxxx', 'image.jpg');
end;
Sign up to request clarification or add additional context in comments.

5 Comments

I tried like below but no change. codevar ABytes: TBytes; AStream: TBytesStream; begin ABytes := TFile.ReadAllBytes('images.jpg'); AStream := TBytesStream.Create(ABytes); RESTRequest1.ClearBody; RESTRequest1.AddBody(AStream);// ByteArrayToString(ABytes)); RESTRequest1.Execute; end;code
It creates a message like: <br/> POST http://s-lywms:2364//OpenAlpr/RecognizeLicensePlates HTTP/1.1 Content-Type: application/x-www-form-urlencoded Accept: application/json, text/plain; q=0.9, text/html;q=0.8, Accept-Charset: UTF-8, *;q=0.8 User-Agent: Embarcadero RESTClient/1.0 Connection: Keep-Alive Content-Length: 0 Host: s-lywms:2364
I can't answer that without digging into the REST client's source code. But why are you reading a file into a TBytes wrapped in a TStream instead of just using a TFileStream directly? var AStream: TFileStream; begin AStream := TFileStream.Create('images.jpg', fmOpenRead); RESTRequest1.ClearBody; RESTRequest1.AddBody(AStream); RESTRequest1.Execute; AStream.Free; end;
Hi Remmy first i want to thank you but your solution creates an empty REST request. There is no body data. And i want to remind that I am not supplier/provider of this service, I am trying to write my client and provider waits a byte array (i think it means TBytes). POST http://s-lywms:2364//OpenAlpr/RecognizeLicensePlates HTTP/1.1 Content-Type: application/x-www-form-urlencoded Accept: application/json, text/plain; q=0.9, text/html;q=0.8, Accept-Charset: UTF-8, *;q=0.8 User-Agent: Embarcadero RESTClient/1.0 Connection: Keep-Alive Content-Length: 0 Host: s-lywms:2364
@RemyLebeau How use RESTRequest1.AddBody(... if have more than one parameter rg. first parameter is image name, second image blob memory stream?
1

I've solved my problem like below:

function BytesToStr(abytes: tbytes): string;
var
  abyte: byte;
begin
   for abyte in abytes do
   begin
      Result := result + IntToStr(abyte) + ',';
   end;
   Result := '[' + Copy(Result, 1, Length(Result) - 1) + ']';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   ABytes: TBytes;
begin
   ABytes := TFile.ReadAllBytes('images.jpg');
   RESTRequest1.Params.AddItem('body', BytesToStr(ABytes), pkREQUESTBODY, [], ctAPPLICATION_JSON);
   RESTRequest1.Execute;
end;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.