Search code examples
delphifiremonkey

Load a png image from the web (delphi fmx)


I would like to load png images from the web, but with the code below not all images do get correctly into the stream (while posting the url in a webbrowser, e.g. edge, does give the image correctly). For example, the first url in the code gives a loading bitmap failed error (in the stream FSize is only 14?), while the second url does not give a problem. Does anyone know how to download the first url correctly?

For this piece of code to work, a TButton and a TImage was put on a form.
System.Net.HttpClientComponent was added in the uses. I am using Delphi 10.3.3. fmx.

Thanks, Gerard

    procedure TForm1.Button1Click(Sender: TObject);
    var ms: TmemoryStream;
        httpCli: TNetHTTPClient;
        url: string;
    begin
      httpCli := TNetHTTPClient.Create(nil);
      ms := TMemoryStream.Create();
    
      url := 'https://a.tile.openstreetmap.org/11/1050/674.png';
  //  url := 'https://upload.wikimedia.org/wikipedia/commons/d/d5/Japan_small_icon.png';
    
      httpCli.Get(url,ms);
      ms.Position := 0;
      Image1.Bitmap.LoadFromStream(ms);
    
      ms.free;
      httpCli.free;
    end;

Solution

  • The problem with the OpenStreetMap tile server is the UserAgent. You must change the default value to something acceptable by the server. I checked a number of possibilities and it looks like almost anything but default value of TNetHTTPClient works. See this Wikipedia article for details.

    To do that, you need to add the line

    httpCli.UserAgent := 'Delphi/4.0 (compatible; Delphi; HttpClient)';
    

    My version of your code which includes HTTP status code checking is the following:

    procedure TForm1.Button1Click(Sender: TObject);
    var
        ms       : TMemoryStream;
        httpCli  : TNetHTTPClient;
        resp     : IHTTPResponse;
        url      : String;
    begin
        httpCli := TNetHTTPClient.Create(nil);
        try
            httpCli.UserAgent := 'Delphi/4.0 (compatible; Delphi; HttpClient)';
            ms := TMemoryStream.Create();
            try
                url  := 'https://a.tile.openstreetmap.org/11/1050/674.png';
                resp := httpCli.Get(url, ms);
                if resp.StatusCode <> 200 then
                    Memo1.Lines.Add(Format('HTTP Error=%d %s',
                                           [resp.StatusCode, resp.StatusText]))
                else begin
                    ms.Position := 0;
                    Image1.Bitmap.LoadFromStream(ms);
                end;
            finally
                ms.Free;
            end;
        finally
            httpCli.Free;
        end;
    end;