urlpngc++buildertimagec++builder-xe8

How do I load png from web into TImage control?


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


Solution

  • 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);
    }