Question

How I can send from a Timage (clientside) to another Timage(serverside)? I'm using delphi XE3 with idtcpclient1, idtcpserver1 (indy10 component). I already tried to do something but I had some trouble.

Server side:

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

Client side:

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

Solution 2

Your question is unclear, but it seems that you're trying to transfer the content of one 'TImage' (on the client) to a TImage on the server. It's unclear whether you mean an image file or an actual TImage, though. I'm going to go with "the picture being displayed in a TImage on the client" being sent to the server. You can use TMemoryStream instead of TFileStream. If you really mean to send the image displayed in a TImage.Picture, you can do something like this (untested):

// 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;

If that's not what you want, edit your question so we can understand what you're trying to do. (Don't tell us in comments, but actually edit your question to make it more clear.)

OTHER TIPS

Example implementation for the transfer of different graphic formats.

Main issue is that you will have to create an appropriate GraphicClass.
If an image is loaded from a file the class is determinate from the file extension.
In this implemetation we add the information to the stream.

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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top