1

如何从 Timage(客户端)发送到另一个 Timage(服务器端)?我正在使用带有 idtcpclient1、idtcpserver1(indy10 组件)的 delphi XE3。我已经尝试过做某事,但遇到了一些麻烦。

服务器端:

FileStream := TFileStream.Create('ciao.jpg', fmCreate);
AContext.Connection.IOHandler.LargeStream := True;
AContext.Connection.IOHandler.ReadStream(FileStream); FileStream.Free;
image1.Picture.LoadFromFile(sname);

客户端:

idTCPClient1.IOHandler.LargeStream := True;
FileStream := TFileStream.Create('hello.jpg', fmOpenRead);
IdTCPClient1.IOHandler.Write(FileStream,0,true);
filestream.Free;
4

2 回答 2

4

传输不同图形格式的示例实现。

主要问题是您必须创建一个适当的 GraphicClass。
如果从文件加载图像,则类由文件扩展名确定。
在这个实现中,我们将信息添加到流中。

unit Unit1;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdContext, Vcl.ExtCtrls, IdTCPConnection, IdTCPClient, IdBaseComponent,
  IdComponent, IdCustomTCPServer, IdTCPServer, Vcl.StdCtrls, Vcl.Imaging.jpeg;

type
  TForm1 = class(TForm)
    IdTCPServer1: TIdTCPServer;
    IdTCPClient1: TIdTCPClient;
    Source: TImage;
    Dest: TImage;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure IdTCPServer1Execute(AContext: TIdContext);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation
uses PNGImage;

{$R *.dfm}

//Enable transfer of different graphicformats

procedure Picture2Stream(DestStream: TMemoryStream; Picture: TPicture);
var
  ms2: TMemoryStream;
  TheClassName: AnsiString;
  len: Byte;
begin
  TheClassName := Picture.Graphic.ClassName;
  len := Length(TheClassName);
  DestStream.WriteBuffer(len, 1);
  if len > 0 then     // save GraphicClass name
    DestStream.WriteBuffer(TheClassName[1], len);
  ms2 := TMemoryStream.Create;
  try                // save graphic
    Picture.Graphic.SaveToStream(ms2);
    ms2.Position := 0;
    if ms2.Size > 0 then
      DestStream.CopyFrom(ms2, ms2.Size);
  finally
    ms2.Free;
  end;
end;

Procedure LoadPictureFromStream(Picture: TPicture; SourceStream: TMemoryStream);
var
  ms2: TMemoryStream;
  len: Byte;
  TheClassName: AnsiString;
  Graphic: TGraphic;
  GraphicClass: TGraphicClass;
begin
  SourceStream.Position := 0;
  SourceStream.ReadBuffer(len, 1);
  SetLength(TheClassName, len);
  if len > 0 then    // read GraphicClass name
    SourceStream.ReadBuffer(TheClassName[1], len);
  GraphicClass := TGraphicClass(FindClass(TheClassName)); //(*)
  if (GraphicClass <> nil) and (len > 0) then
  begin
    Graphic := GraphicClass.Create;  // create appropriate graphic class
    try
      ms2 := TMemoryStream.Create;
      try
        ms2.CopyFrom(SourceStream, SourceStream.Size - len - 1);
        ms2.Position := 0;
        Graphic.LoadFromStream(ms2);
      finally
        ms2.Free;
      end;
      Picture.Assign(Graphic);
    finally
      Graphic.Free;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ms: TMemoryStream;
begin
  ms := TMemoryStream.Create;
  try
    Picture2Stream(ms, Source.Picture);
    ms.Position := 0;
    IdTCPClient1.Host := '127.0.0.1';
    IdTCPClient1.Port := 12345;
    IdTCPClient1.Connect;
    IdTCPClient1.IOHandler.LargeStream := true;
    IdTCPClient1.IOHandler.Write(ms, ms.Size, true);
  finally
    ms.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  IdTCPServer1.DefaultPort := 12345;
  IdTCPServer1.Active := true;
  ReportMemoryLeaksOnShutDown := true;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
  ms: TMemoryStream;
begin
  ms := TMemoryStream.Create;
  try
    AContext.Connection.IOHandler.LargeStream := true;
    AContext.Connection.IOHandler.ReadStream(ms);
    TThread.Synchronize(nil,
      Procedure
      begin
        LoadPictureFromStream(Dest.Picture, ms);
      end);
  finally
    ms.Free;
  end;
end;

initialization
// RegisterClasses to enable FindClass (*)
RegisterClasses([TIcon, TMetafile, TBitmap, TJPEGImage, TPngImage]);

end.
于 2013-05-17T13:41:57.140 回答
2

您的问题尚不清楚,但您似乎正在尝试将一个“TImage”(在客户端)的内容传输到TImage服务器上的一个。不过,尚不清楚您是指图像文件还是实际TImage的 . 我打算将“图片在客户端的 TImage 中显示”发送到服务器。您可以使用TMemoryStream而不是TFileStream. 如果您真的打算发送显示在 a 中的图像TImage.Picture,您可以执行以下操作(未经测试):

// Server side
var
  Jpg: TJpegImage;
begin
  Strm := TMemoryStream.Create;
  try
    Strm.Position := 0;
    AContext.Connection.IOHandler.LargeStream := True;
    AContext.Connection.IOHandler.ReadStream(Strm);
    Strm.Position := 0;
    Jpg := TJpegImage.Create;
    try
      Jpg.LoadFromStream(Strm);
      Image1.Picture.Assign(Jpg);
    finally
      Jpg.Free;
    end;
  finally
    Strm.Free;
  end;
end;

// Client side
IdTCPClient1.IOHandler.LargeStream := True;
Strm := TMemoryStream.Create;
try
  Image1.Picture.Graphic.SaveToStream(Strm);
  Strm.Position := 0;
  IdTCPClient1.IOHandler.Write(Strm, 0, True);
finally
  Strm.Free;
end;

如果这不是您想要的,请编辑您的问题,以便我们了解您想要做什么。(不要在评论中告诉我们,但实际上编辑您的问题以使其更清楚。)

于 2013-05-17T13:02:10.067 回答