[英]delphi, send image with indy10 from client to server
How I can send from a Timage (clientside) to another Timage(serverside)? 如何从一个Timage(客户端)发送到另一个Timage(服务器端)? I'm using delphi XE3 with idtcpclient1, idtcpserver1 (indy10 component). 我正在将delphi XE3与idtcpclient1,idtcpserver1(indy10组件)一起使用。 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;
Example implementation for the transfer of different graphic formats. 传输不同图形格式的示例实现。
Main issue is that you will have to create an appropriate GraphicClass. 主要问题是您将必须创建适当的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.
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. 您的问题尚不清楚,但似乎您正在尝试将一个“ TImage”(在客户端上)的内容传输到服务器上的TImage
。 It's unclear whether you mean an image file or an actual TImage
, though. 目前尚不清楚您是指图像文件还是实际的TImage
。 I'm going to go with "the picture being displayed in a TImage on the client" being sent to the server. 我将“将图片显示在客户端上的TImage中”发送给服务器。 You can use TMemoryStream
instead of TFileStream
. 您可以使用TMemoryStream
代替TFileStream
。 If you really mean to send the image displayed in a TImage.Picture
, you can do something like this (untested): 如果您真的想发送显示在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;
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.) (不要在评论中告诉我们,而是实际编辑您的问题以使其更清楚。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.