我曾经写过的,希望对你有用
利用流传送图像
在远程控制系统中常常需要在远端查看主机屏幕,一般的思路是客户端发给服务端一个请求,服务端接收请求后执行发送图像的指令,此处的难点是如何以流方式传送图像。下面的程序示例演示了这样的功能:客户端连到服务端后,服务端点发送图像的按钮后,即开始传送图像,客户端界面上的图像框里立即显示此图像。
1.服务器端代码
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, ScktComp, StdCtrls,Jpeg;
type
TForm2 = class(TForm)
Button1: TButton;
ss: TServerSocket;
Image1: TImage;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ssAccept(Sender: TObject; Socket: TCustomWinSocket);
procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
procedure sendscreen();
public
{ Public declarations }
end;
var
Form2: TForm2;
jpegscreen:Tjpegimage;
jpegstream:Tmemorystream;
LeftSize:Longint;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
var
Buf:array[0..2047] of char;
begin
jpegscreen:=Tjpegimage.Create ;
jpegscreen.Assign (image1.Picture.bitmap);
jpegscreen.CompressionQuality:=40;
image1.Picture.bitmap.SaveToStream(jpegstream); //创建Jpeg压缩流
//jpegscreen.SaveToStream(jpegstream);
leftsize:=jpegstream.Size;
jpegstream.Position:=0;
sendscreen;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
ss.active:=true;
jpegstream:=Tmemorystream.Create;
end;
procedure TForm2.sendscreen;
var
sendsize:longint;
Buf:array[0..2048-1] of char;
begin
//if jpegstream.Size =0 then snapscreen();
if LeftSize>2048 then SendSize:=2048 else SendSize:=leftsize;
jpegStream.ReadBuffer(Buf,sendsize);
LeftSize:=LeftSize-SendSize;
if LeftSize=0 then jpegStream.Clear;
try
ss.Socket.Connections[0].SendBuf (buf,sendsize);
except
jpegstream.Clear ;
end;
end;
procedure TForm2.ssAccept(Sender: TObject; Socket: TCustomWinSocket);
begin
socket.Lock
end;
procedure TForm2.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var sendsize:longint;
Buf:array[0..2048-1] of char;
begin
if socket.ReceiveText='show' then
begin
sendscreen;
end;
end;
end.
2.客户端代码
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, ExtCtrls,Jpeg, Menus;
type
TForm1 = class(TForm)
Image1: TImage;
cs: TClientSocket;
MainMenu1: TMainMenu;
N1: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure csRead(Sender: TObject; Socket: TCustomWinSocket);
procedure csConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure N1Click(Sender: TObject);
procedure N3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
jpegscreen:Tjpegimage;
jpegstream:Tmemorystream;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
cs.Address:='127.0.0.1';
cs.Port:=6767;
cs.Active:=true;
jpegscreen:=Tjpegimage.Create ;
jpegstream:= Tmemorystream.Create;
jpegstream.position:=0;
end;
procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);
var
buf:array[0..2047] of char;
numberbytes:integer;
begin
numberbytes:=socket.ReceiveLength;
socket.receiveBuf(buf,numberbytes);
socket.SendText('show');
jpegstream.Write(buf,numberbytes);
if numberbytes<2048 then //开始接收图像流
begin
jpegstream.Position :=0;
try
image1.Picture.Bitmap.LoadFromStream(jpegstream);
//jpegscreen.LoadFromStream(jpegstream);
// image1.Picture.Bitmap.Assign(jpegscreen);
jpegstream.SaveToFile('1.bmp');
//jpegscreen.LoadFromStream(jpegstream);
//image1.Picture.bitmap.Assign(jpegscreen);
except
end;
jpegstream.Clear ;
end;
end;
procedure TForm1.csConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
showmessage('connected with'+cs.address+'!');
end;
procedure TForm1.N1Click(Sender: TObject); //保存图像
var savedialog:Tsavedialog;
begin
try
savedialog:=tsavedialog.Create(self);
if image1.Picture<>nil then
begin
savedialog.Execute;
image1.Picture.SaveToFile(savedialog.FileName);
end;
except
on e:exception do showmessage(e.Message);
end;
end;
procedure TForm1.N3Click(Sender: TObject); //打印图像过程
var strect: Trect; //定义打印输出矩形框的大小
temhi, temwd: integer;
printdialog1:tprintdialog;
begin
printdialog1:=tprintdialog.Create(self);
if image1.Picture.Graphic <> nil then
begin
if printdialog1.execute then
begin
temhi := image1.picture.height;
temwd := image1.picture.width;
while (temhi <= printer.pageheight div 2) and (temwd <= printer.pagewidth div 2) do
//将图形放大到打印页面的1/2大小
begin
temhi := temhi + temhi;
temwd := temwd + temwd;
end;
with strect do //定义图形在页面上的中心位置输出
begin
left := (printer.pagewidth - temwd) div 2;
top := (printer.pageheight - temhi) div 2;
right := left + temwd;
bottom := top + temhi;
end;
with printer do
begin
begindoc;
canvas.stretchdraw(strect, image1.picture.graphic);
//将放大的图形向打印机输出
enddoc;
end;
end;
end
else
showmessage('没有可用的图片供打印!');
end;
end.