Delphi Indy 流式 Http 服务器

4

相机捕捉图像。
我希望通过HTTP可以访问这张图片。
我能否使用TIdHTTPServer.OnCommandGet事件来显示它?
我只想在TImage中实时显示该图片。
如果可以,具体怎么做呢?


抱歉,我完全不知道你想问什么。首先,你所说的“captures the image to the image”是什么意思? - Jerry Dodge
这是一个带有TImage控件的VCL表单应用程序吗?我只是猜测。但这只解决了你问题的10%。 - Jerry Dodge
所以我使用VCL Timage并希望在侧边显示他的照片。通过Http服务器实现。 - lukasz skrzypczak
客户端和服务器分别是哪一方?你是想从服务器发送图像到客户端还是从客户端发送到服务器?请记住,这里没有人能读懂你的想法。 - Jerry Dodge
抱歉我的英语不好,我使用翻译工具来帮助...。".HTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); begin AResponseInfo.ContentText:= Image1.Bitmap "他想让服务器只显示相机图像或Timage。在浏览器中输入本地主机并向我展示实时摄像头图片。 - lukasz skrzypczak
显示剩余3条评论
2个回答

5
如果您只需要在客户端请求时显示最新的图片,可以像这样做:
type
  TGetImageStream = class(TIdSync)
  protected
    FStream: TStream;
    procedure DoSynchronize; override;
  public
    class procedure GetImage(Stream: TStream);
  end;

procedure TGetImageStream.DoSynchronize;
begin
  Form1.Image1.Bitmap.SaveToStream(FStream);
end;

class procedure TGetImageStream.GetImage(Stream: TStream);
begin
  with Create do
  try
    FStream := Stream;
    Synchronize;
  finally
    Free;
  end;
end;

procedure TForm1.HTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  Strm: TMemoryStream;
begin
  Strm := TMemoryStream.Create;
  try
    TGetImageStream.GetImage(Strm);
    Strm.Position := 0;
  except
    Strm.Free;
    raise;
  end;
  AResponseInfo.ResponseNo := 200;
  AResponseInfo.ContentType := 'image/bmp';
  AResponseInfo.ContentStream := Strm;
end;

但如果您需要实时直播相机图像,则会变得有些棘手。您可以以几种不同的方式进行操作。例如,使用客户端拉取:

procedure TForm1.HTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  Strm: TMemoryStream;
begin
  if ARequestInfo.Document = '' then
  begin
    AResponseInfo.Redirect('/');
  end
  else if ARequestInfo.Document = '/' then
  begin
    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentType := 'text/html';
    AResponseIno.ContentText := '<html>'+EOL+
                                '<head>'+EOL+
                                '<title>Camera Image</title>'+EOL+
                                '<meta http-equiv="Refresh" content=5>'+EOL+
                                '</head>'+EOL+
                                '<body>'+EOL+
                                '<img src="/image">'+EOL+
                                '</body>'+EOL+
                                '</html>'+EOL;
  end
  else if ARequestInfo.Document = '/image' then
  begin
    Strm := TMemoryStream.Create;
    try
      TGetImageStream.GetImage(Strm);
      Strm.Position := 0;
    except
      Strm.Free;
      raise;
    end;
    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentType := 'image/bmp';
    AResponseInfo.ContentStream := Strm;
  end else begin
    AResponseInfo.ResponseNo := 404;
  end;
end;

使用服务器推送替代:
procedure TForm1.HTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  Strm: TMemoryStream;
begin
  Strm := TMemoryStream.Create;
  try
    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentType := 'multipart/x-mixed-replace; boundary=imgboundary';
    AResponseInfo.CloseConnection := False;
    AResponseInfo.WriteHeader;

    AContext.Connection.IOHandler.WriteLn('--imgboundary');
    repeat
      Strm.Clear;
      TGetImageStream.GetImage(Strm);

      AContext.Connection.IOHandler.WriteLn('Content-type: image/bmp');
      AContext.Connection.IOHandler.WriteLn;
      AContext.Connection.IOHandler.Write(Strm);
      AContext.Connection.IOHandler.WriteLn;
      AContext.Connection.IOHandler.WriteLn('--imgboundary');

      Sleep(5000);
   until False;
  finally
    Strm.Free;
  end;
end;

谢谢你!你帮了我,我只是一个编程的初学者,想向最好的人学习 ;) - lukasz skrzypczak
作为一个单独的应用程序来接收这个图像到Timage? - lukasz skrzypczak
webbrowser.navigate('localhost');?想要与另一个应用程序一起使用,以便您可以查看图片。 - lukasz skrzypczak
如果您想制作一个接收图像的应用程序,只需让它发出HTTP请求,而不是使用浏览器。由于您已经在服务器上使用了Indy的TIdHTTPServer,因此可以使用Indy的TIdHTTP作为客户端:IdHTTP1.Get('http://localhost/image', Strm); Strm.Position := 0; Image1.Picture.Bitmap.LoadFromStream(Strm);。或者还有很多其他支持HTTP的第三方组件/库可用 - ICS、Synapse、libcurl、WinInet/WinHTTP等。 - Remy Lebeau

0
Remy,WriteHeader 似乎会写入 "Content-Length: 0" 的内容。它确实如预期地工作 - 但如果您手动编写标题并排除 Content-Length,则可以正常工作。

这不是对所提出问题的回答。它应该作为评论发布。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接