2

I have several small .PNG pictures I wan't to load from a web-address and into TImage images in my application. The pictures are "dynamic", so I don't want to "hardcode" them into my app by using TImageList etc.

I have seen several examples, but none of them can give me a straight way to do this.

I know I can use TWebBrowser to solve this, but it seems to obscure my application and is not aligned to the alignment i set it to either.

Any good suggestions ?

My platform is Android, I am using Embarcadero C++Builder XE8 / Appmethod 1.17

manlio
  • 18,345
  • 14
  • 76
  • 126
Roar Grønmo
  • 2,926
  • 2
  • 24
  • 37

1 Answers1

3

In FireMonkey, the FMX.Graphics.TBitmap class handles multiple image formats, including PNG. The FMX.Objects.TImage component has a Bitmap property. All you have to do is use Indy's TIdHTTP component (or any other HTTP API/library of your choosing) to download the PNG image data into a TMemoryStream, and then you can call the TImage::Bitmap::LoadFromStream() method to load the stream data for display, for example:

TMemoryStream *strm = new TMemoryStream;
IdHTTP1->Get(L"http://domain/image.png", strm);
strm->Position = 0;
Image1->Bitmap->LoadFromStream(strm);

Since downloading from a remote server can take time, and you should never block the UI thread, you should use a worker thread to handle the download, for example:

class TDownloadThread : public TThread
{
protected:
    virtual void __fastcall Execute()
    {
        TIdHTTP *Http = new TIdHTTP(NULL);
        Http->Get(L"http://domain/image.png", Strm);
        Strm->Position = 0;
    }

public:
    TMemoryStream *Strm;

    __fastcall TDownloadThread()
        : TThread(true)
    {
        FreeOnTerminate = true;
        Strm = new TMemoryStream;
    }
};

void __fastcall TMyForm::DownloadImage()
{
    TDownloadThread *Thread = new TDownloadThread();
    Thread->OnTerminate = &DownloadThreadFinished;
    Thread->Start();
}

void __fastcall TMyForm::DownloadThreadFinished(TObject *Sender)
{
    TDownloadThread *Thread = static_cast<TDownloadThread*>(Sender);
    if (!Thread->FatalException)
        Image1->Bitmap->LoadFromStream(Thread->Strm);
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for the reply Remy!! I will test this out !! By the way, is FMX thread safe ? – Roar Grønmo Mar 22 '16 at 20:18
  • In my attempt to reply my own question I got pinned down... anyhow I'll paste it here: "It works !... when I use 'http://www.domain.com/image.png'. But if the picture is an image from i.e. Google's static maps i get problems. The response should be a png, but it seems that I am getting a "fatal error". If I copy the URL to my webbrowser it is ok though. Do I need to set some parameters in the IdHTTP client? Anyhow, you solved half of my problems... I appriciate that !! "Keep on & Stay on" RG" – Roar Grønmo Mar 23 '16 at 12:23
  • ... and I found a solution for the problem with the "Fatal Error", (actually it was the TIdHTTP::Request::UserAgent parameter which was set to "Mozilla/3.0 (compatible; Indy Library)" which somehow had been compromized, and now is denied. Searching around in the indy libraries i found this: http://www.indyproject.org/kb/index.html?iamgettinga403forbiddene.htm So changing this paramter to "Mozilla/3.0 (compatible; 'Application name')" Where 'Application name' is the name of my application, it seems to work just fine. – Roar Grønmo Mar 23 '16 at 12:32