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

あなたの質問は明確ではありませんが、1 つの「TImage」(クライアント上) のコンテンツをサーバー上の に転送しようとしているようですTImageただし、画像ファイルを意味するのか実際のファイルを意味するのかは不明TImageです。「クライアントの TImage に表示されている画像」がサーバーに送信されます。TMemoryStreamの代わりに使用できますTFileStream。に表示された画像を本当に送信する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 に答える