从网络加载 png 图像 (delphi fmx)
Load a png image from the web (delphi fmx)
我想从网络加载 png 图像,但是使用下面的代码并不是所有图像都能正确地进入流(在网络浏览器中发布 url 时,例如边缘,确实给出了图像正确)。比如代码中第一个url给出loading bitmap failed错误(流中FSize只有14?),而第二个url没有给出问题。有谁知道如何正确下载第一个url?
为了使这段代码起作用,将一个 TButton 和一个 TImage 放在一个表单上。
System.Net.HttpClientComponent 已添加到使用中。我正在使用 Delphi 10.3.3。 fmx.
谢谢,
杰拉德
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;
在 HTTP 上操作时,您必须检查 HTTP 服务器是否可以满足您的请求 (status code 200, as per RFC7231, § 6.3.1) or any error occured. In your case requesting that URI and making sure to see what comes from the server can be done with i.e. wget:
wget -S --content-on-error https://a.tile.openstreetmap.org/11/1050/674.png
这将打印服务器的响应 headers 并且在任何情况下都会创建一个包含负载的文件。响应 headers 是(摘录):
HTTP/1.1 403 Forbidden
Content-Length: 14
这意味着:您无权查询该资源(HTTP 状态代码 403)。有效负载保存在一个大小为 14 字节的文件中,其中包含 14 个 ASCII 字符的文本:
Access denied.
琐事:最小的有效 PNG 文件大小至少为 67 字节(阅读 "Smallest possible transparent PNG" by Gareth Rees。
OpenStreetMap 图块服务器的问题是 UserAgent。您必须将默认值更改为服务器可接受的值。我检查了多种可能性,看起来几乎任何东西都可以,但 TNetHTTPClient
的默认值有效。有关详细信息,请参阅此 Wikipedia article。
为此,您需要添加行
httpCli.UserAgent := 'Delphi/4.0 (compatible; Delphi; HttpClient)';
我的包含 HTTP 状态代码检查的代码版本如下:
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;
我想从网络加载 png 图像,但是使用下面的代码并不是所有图像都能正确地进入流(在网络浏览器中发布 url 时,例如边缘,确实给出了图像正确)。比如代码中第一个url给出loading bitmap failed错误(流中FSize只有14?),而第二个url没有给出问题。有谁知道如何正确下载第一个url?
为了使这段代码起作用,将一个 TButton 和一个 TImage 放在一个表单上。
System.Net.HttpClientComponent 已添加到使用中。我正在使用 Delphi 10.3.3。 fmx.
谢谢, 杰拉德
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;
在 HTTP 上操作时,您必须检查 HTTP 服务器是否可以满足您的请求 (status code 200, as per RFC7231, § 6.3.1) or any error occured. In your case requesting that URI and making sure to see what comes from the server can be done with i.e. wget:
wget -S --content-on-error https://a.tile.openstreetmap.org/11/1050/674.png
这将打印服务器的响应 headers 并且在任何情况下都会创建一个包含负载的文件。响应 headers 是(摘录):
HTTP/1.1 403 Forbidden
Content-Length: 14
这意味着:您无权查询该资源(HTTP 状态代码 403)。有效负载保存在一个大小为 14 字节的文件中,其中包含 14 个 ASCII 字符的文本:
Access denied.
琐事:最小的有效 PNG 文件大小至少为 67 字节(阅读 "Smallest possible transparent PNG" by Gareth Rees。
OpenStreetMap 图块服务器的问题是 UserAgent。您必须将默认值更改为服务器可接受的值。我检查了多种可能性,看起来几乎任何东西都可以,但 TNetHTTPClient
的默认值有效。有关详细信息,请参阅此 Wikipedia article。
为此,您需要添加行
httpCli.UserAgent := 'Delphi/4.0 (compatible; Delphi; HttpClient)';
我的包含 HTTP 状态代码检查的代码版本如下:
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;