Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: [Berlin] How to get an image from a REST Server to a REST Client ?


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 3 - Last Post: Jul 16, 2016 4:38 PM Last Post By: Remy Lebeau (Te...
Guest
[Berlin] How to get an image from a REST Server to a REST Client ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 13, 2016 7:42 AM
Bonjour,

Do you know a sample C++ code for that :
Imagine on a REST Client (Android for exemple), i click on a button, and it downloads an image from a REST Server.

Do you know a such sample ?

Best regards

Gabriel
Sean Hoffman

Posts: 126
Registered: 3/28/99
Re: [Berlin] How to get an image from a REST Server to a REST Client ?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 13, 2016 7:57 AM   in response to: Guest in response to: Guest
GRIPARI Gabriel wrote:
Bonjour,

Do you know a sample C++ code for that :
Imagine on a REST Client (Android for exemple), i click on a button, and it downloads an image from a REST Server.

Do you know a such sample ?

Best regards

Gabriel

Remember a REST client is really an HTTP client. So what you're really looking for is a means to make an HTTP call to retrieve a resource on a server. That REST service implementation is almost certainly a GET call. There are a couple of ways to handle this. You could:

1. Use Indy, specifically the TIdHTTP class
2. Use the Rest client, see tutorial here: http://docwiki.embarcadero.com/RADStudio/XE8/en/Tutorial:_Using_the_REST_Client_Library_to_Access_REST-based_Web_Services
Guest
Re: [Berlin] How to get an image from a REST Server to a REST Client ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 16, 2016 12:44 PM   in response to: Sean Hoffman in response to: Sean Hoffman
Bonjour,

For those who are interessed by the code :

1. Use Indy, specifically the TIdHTTP class

UnicodeString URL = "http://192.168.1.5:8082/Paysage.png";

System::Classes::TMemoryStream* ResponseContent = new System::Classes::TMemoryStream;
IdHTTP1->Get(URL, ResponseContent);
try
{Image1->Bitmap = new Fmx::Graphics::TBitmap(ResponseContent);
}
__finally
{ delete ResponseContent;
} ;
Image1->Bitmap->SaveToFile("Paysage.png");


UnicodeString LUrl = "http://192.168.1.5:8082/Paysage.png";
System::Classes::TMemoryStream* LStream = NULL;
try
{LStream = new System::Classes::TMemoryStream();
Rest::Client::TDownloadURL::DownloadRawBytes(LUrl, LStream);
Image1->Bitmap->LoadFromStream(LStream);
}
__finally
{delete LStream;
}

This second code does not work. At the execution :
Error from d'IIS 10.0 - 406.0 - not Acceptable

Any idea ?

Best regards.

Gabriel

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: [Berlin] How to get an image from a REST Server to a REST Client ?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 16, 2016 4:38 PM   in response to: Guest in response to: Guest
GRIPARI wrote:

System::Classes::TMemoryStream* ResponseContent = new
System::Classes::TMemoryStream;
IdHTTP1->Get(URL, ResponseContent);
try
{Image1->Bitmap = new Fmx::Graphics::TBitmap(ResponseContent);
}
__finally
{ delete ResponseContent;
} ;
Image1->Bitmap->SaveToFile("Paysage.png");

There are several problems with that snippet.

1. If TIdHTTP::Get() raises an exception, such an an HTTP error, you will
leak the TMemoryStream object. Your try/finally is at the wrong level in
the code, the Get() needs to be inside of the try block, not outside of it.

2. You need to set the stream's Position back to 0 after downloading, otherwise
TBitmap will not actually load anything.

3. The TImage::Bitmap property setter makes copy of the source TBitmap's
data. It does not take ownership of the source TBitmap, like you are expecting.
So, you are leaking your loaded TBitmap object.

Try this instead:

System::Classes::TMemoryStream* ResponseContent = new System::Classes::TMemoryStream;
try
{
    IdHTTP1->Get(URL, ResponseContent);
    ResponseContent->Position = 0;
 
    Fmx::Graphics::TBitmap *pBitmap = new Fmx::Graphics::TBitmap(ResponseContent);
    try
    {
        Image1->Bitmap = pBitmap;
    }
    __finally
    {
        delete pBitmap;
    }
}
__finally
{
    delete ResponseContent;
}
Image1->Bitmap->SaveToFile("Paysage.png");


Alternatively:

System::Classes::TMemoryStream* ResponseContent = new System::Classes::TMemoryStream;
try
{
    IdHTTP1->Get(URL, ResponseContent);
    ResponseContent->Position = 0;
    Image1->Bitmap->LoadFromStream(ResponseContent);
}
__finally
{
    delete ResponseContent;
}
Image1->Bitmap->SaveToFile("Paysage.png");


If you use the STL std::auto_ptr (pre-C++11) or std::unique_ptr (C++11) class,
you can get rid of the try/finally blocks altogether:

#include <memory>
 
std::unique_ptr<System::Classes::TMemoryStream> ResponseContent(new System::Classes::TMemoryStream);
 
IdHTTP1->Get(URL, ResponseContent.get());
ResponseContent->Position = 0;
 
std::unique_ptr<Fmx::Graphics::TBitmap> pBitmap(new Fmx::Graphics::TBitmap(ResponseContent.get()));
Image1->Bitmap = pBitmap.get();
 
Image1->Bitmap->SaveToFile("Paysage.png");


Alternatively:

std::unique_ptr<System::Classes::TMemoryStream> ResponseContent(new System::Classes::TMemoryStream);
 
IdHTTP1->Get(URL, ResponseContent.get());
ResponseContent->Position = 0;
 
Image1->Bitmap->LoadFromStream(ResponseContent.get());
Image1->Bitmap->SaveToFile("Paysage.png");


If you just need to save the downloaded data to file, and not actually display
it to the user, then just ignore TImage altogether:

#include <memory>
 
std::unique_ptr<System::Classes::TMemoryStream> ResponseContent(new System::Classes::TMemoryStream);
 
IdHTTP1->Get(URL, ResponseContent.get());
ResponseContent->Position = 0;
 
std::unique_ptr<Fmx::Graphics::TBitmap>(new Fmx::Graphics::TBitmap(ResponseContent.get()))->SaveToFile("Paysage.png");


Or even:

#include <memory>
 
std::unique_ptr<System::Classes::TMemoryStream> ResponseContent(new System::Classes::TMemoryStream);
 
IdHTTP1->Get(URL, ResponseContent.get());
ResponseContent->Position = 0;
 
ResponseContent->SaveToFile("Paysage.png");


Alternatively:

#include <memory>
 
std::unique_ptr<System::Classes::TFileStream> ResponseContent(new System::Classes::TFileStream("Paysage.png", 
fmCreate));
IdHTTP1->Get(URL, ResponseContent.get());

This second code does not work. At the execution : Error from
d'IIS 10.0 - 406.0 - not Acceptable

An HTTP 406 error means the client sent an "Accept" request header describing
the data format(s) it is willing (or not willing) to accept for download,
and the server generated a response in a format that the client is not willing
to accept. REST is typically used for (but not restricted to) retreiving
XML/JSON documents, not raw binary data. So either TDownloadURL is sending
a bad "Accept" header, or the server is trying to send back something other
than what the client is actually requesting.

By default, TIdHTTP sends an "Accept" header that accepts all formats (though
it has a higher preference for HTML/XML, if the server can provide multiple
representations of the same data).

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02