我在Delphi5中我需要1秒钟抓屏至少7次,然后通过Picture显示出来!怎样解决?提供思路者50大洋奉上!提供源代码者200大洋奉上!先来50大洋!(50

W

wanxu

Unregistered / Unconfirmed
GUEST, unregistred user!
我在Delphi5中我需要1秒钟抓屏至少7次,然后通过Picture显示出来!怎样解决?提供思路者50大洋奉上!提供源代码者200大洋奉上!先来50大洋!(50分)<br />我现在正在搞一个局域网管理系统。需要在服务器端对局域网中的某一台计算机进
行屏幕监控,在连接到某台计算机的时候这台计算机的客户端就在1秒钟之内连续
抓屏7次,并且传送到服务器的Picture控件显示出来!这样就达到了监视局域网计
算机的目的。我的思路就是这样!希望高手提出更好而且更简单的思路,如果有源
代码而且确实可以实施,我将另外再加150大洋!
 
抓屏幕的速度是关键啊....
压缩和传输的时间很快的
 
用Timer控件,设置每100ms抓一次。
 
[green]caowei[/green]:我也知道抓屏幕是关键!怎样抓屏???
[yellow]撒野[/yellow]:这个我到会做!我觉得抓屏是关键!!!!

[red]还有人有好办法吗?[/red]
 
这个方案好吗,需要斟酌一下。/
 
//1秒钟之内连续抓屏7次,并且传送到服务器的Picture控件显示出来!
我觉得用摄像头监控更好!我这儿就是用这种方法,性价比挺高的。
很多时候,硬件比软件来得快,效果也更好!
 
我也觉得硬件来得快。
 
你在客户端搞个程序嘛,这样抓屏不就简单多了,在发到服务器上来,呵呵,
不过好象有点过份哟,偷看?!/:)
 
要源吗?吃shit去吧!
 
大家有什么好的意见吗?
我在在其他客户机器上面有客户端,我没有偷窥的意图,就是
紧紧起到一个监控的作用!!
 
那些多媒体教学软件不都是这样的吗
 

{==============================================================================}
{ Use this to capture a rectangle on the screen... }
function CaptureScreenRect( ARect: TRect ): TBitmap;
{==============================================================================}
var
ScreenDC: HDC;
begin

Result := TBitmap.Create;
with Result, ARectdo

begin

Width := Right - Left;
Height := Bottom - Top;
ScreenDC := GetDC( 0 );
try
BitBlt( Canvas.Handle, 0, 0, Width, Height, ScreenDC,
Left, Top, SRCCOPY );
finally
ReleaseDC( 0, ScreenDC );
end;

end;

end;


{==============================================================================}
{ Use this to capture the entire screen... }
function CaptureScreen: TBitmap;
{==============================================================================}
begin

with Screendo

Result := CaptureScreenRect( Rect( 0, 0, Width, Height ));
end;


proceduredo
sendscreen;
var
Jpg: TJPEGImage;
Bmp: TBitmap;
Stm: TMemoryStream;
begin

try
Jpg:= TJPEGImage.Create;
Stm:= TMemoryStream.Create;
Bmp:= CaptureScreen;
try
Jpg.Assign(Bmp);
Jpg.SaveToStream(Stm);
SendJpgStreamToSocket Here...............
finally
Bmp.Free;
Stm.Free;
Jpg.Free
end;

except
do
Exception here;
end;

end;


 
unit ClnUnit;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
NMUDP,jpeg, ExtCtrls;

type
TClient = class(TForm)
cUDP: TNMUDP;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure cUDPDataReceived(Sender: TComponent;
NumberBytes: Integer;
FromIP: String;
Port: Integer);
procedure ScreenCap(LeftPos,TopPos,RightPos,BottomPos:integer);
private
{ Private declarations }
public
{ Public declarations }
end;


var
Client: TClient;

implementation
const BufSize=2048;{ 发送每一笔数据的缓冲区大小 }
var
BmpStream:TMemoryStream;
myjpeg: TJPEGImage;
LeftSize:Longint;{ 发送每一笔数据后剩余的字节数 }
Bitmap:TBitmap;

{$R *.DFM}

procedure TClient.FormCreate(Sender: TObject);
begin

BmpStream:=TMemoryStream.Create;
myjpeg := TJPEGImage.Create;
// 创建JPEG图象
Bitmap:=TBitmap.Create;
end;


procedure TClient.FormDestroy(Sender: TObject);
begin

BmpStream.Free;
myjpeg.Free;
// 释放资源
Bitmap.Free;
end;


procedure TClient.cUDPDataReceived(Sender: TComponent;
NumberBytes: Integer;
FromIP: String;
Port: Integer);
var
CtrlCode:array[0..29] of char;
Buf:array[0..BufSize-1] of char;
TmpStr:string;
SendSize,LeftPos,TopPos,RightPos,BottomPos:integer;
begin

CUDP.ReadBuffer(CtrlCode,NumberBytes);{ 读取控制码 }
if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='show' then

begin
{ 控制码前4位为“show”表示主控机发出了抓屏指令 }
if BmpStream.Size=0 then
{ 没有数据可发,必须截屏生成数据 }
begin

TmpStr:=StrPas(CtrlCode);
TmpStr:=Copy(TmpStr,5,Length(TmpStr)-4);
LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)
-Pos(':',TmpStr));
TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)-
Pos(':',TmpStr));
RightPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
BottomPos:=StrToInt(Copy(TmpStr,Pos(':',TmpStr
)+1,Length(TmpStr)-Pos(':',TmpStr)));

ScreenCap(LeftPos,TopPos,RightPos,BottomPos);
{ 截取屏幕 }
end;

if LeftSize>BufSize then
SendSize:=BufSize
else
SendSize:=LeftSize;
BmpStream.ReadBuffer(Buf,SendSize);
LeftSize:=LeftSize-SendSize;
if LeftSize=0 then
BmpStream.Clear;{ 清空流 }
CUDP.RemoteHost:=FromIP;
{ FromIP为主控机IP地址 }
CUDP.SendBuffer(Buf,SendSize);
{ 将数据发到主控机的2222口 }
end;

//------------------
if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='move' then

begin

TmpStr:=StrPas(CtrlCode);
TmpStr:=Copy(TmpStr,5,Length(TmpStr)-4);
LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)-Pos(':',TmpStr));
TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
mouse_event(MOUSEEVENTF_MOVE or MOUSEEVENTF_ABSOLUTE,LeftPos*65535 div 800,TopPos * 65535 div 600,0,GetMessageExtraInfo());
end;

if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='ldon' then

begin

TmpStr:=StrPas(CtrlCode);
TmpStr:=Copy(TmpStr,5,Length(TmpStr)-4);
LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)-Pos(':',TmpStr));
TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
mouse_event(MOUSEEVENTF_LEFTDOWN or MOUSEEVENTF_ABSOLUTE,LeftPos*65535 div 800,TopPos * 65535 div 600,0,GetMessageExtraInfo());
end;

if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='lbup' then

begin

TmpStr:=StrPas(CtrlCode);
TmpStr:=Copy(TmpStr,5,Length(TmpStr)-4);
LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)-Pos(':',TmpStr));
TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
mouse_event(MOUSEEVENTF_LEFTUP or MOUSEEVENTF_ABSOLUTE,LeftPos*65535 div 800,TopPos * 65535 div 600,0,GetMessageExtraInfo());
end;

if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='rdon' then

begin

TmpStr:=StrPas(CtrlCode);
TmpStr:=Copy(TmpStr,5,Length(TmpStr)-4);
LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)-Pos(':',TmpStr));
TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
mouse_event(MOUSEEVENTF_RIGHTDOWN or MOUSEEVENTF_ABSOLUTE,LeftPos*65535 div 800,TopPos * 65535 div 600,0,GetMessageExtraInfo());
end;

if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='rbup' then

begin

TmpStr:=StrPas(CtrlCode);
TmpStr:=Copy(TmpStr,5,Length(TmpStr)-4);
LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)-Pos(':',TmpStr));
TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
mouse_event(MOUSEEVENTF_RIGHTUP or MOUSEEVENTF_ABSOLUTE,LeftPos*65535 div 800,TopPos * 65535 div 600,0,GetMessageExtraInfo());
end;


end;


procedure TClient.ScreenCap(LeftPos,TopPos,RightPos,BottomPos:integer);

begin


Bitmap.Width:=800;
Bitmap.Height:=600;
Bitmap.PixelFormat:=pf8bit;
Application.ProcessMessages;
BitBlt(bitmap.Canvas.Handle,0,0,800,600,getdc(0),
0,0,SRCCOPY);

myjpeg.Assign(bitmap);
Application.ProcessMessages;
//myjpeg.compress;
//myjpeg.CompressionQuality := 4;
myjpeg.SaveToStream(BmpStream);
BmpStream.Position:=0;
LeftSize:=BmpStream.Size;
Application.ProcessMessages;
end;



end.
 
上面的操作无法满足 7 fps 的要求的。
 
pcAnyWhere10.0在Internet环境下都可以做到,局域网做不到?关键是思路与算法,
方法1.破解pcAnyWhere得到源代码,研究
方法2.在客户机上装个pcAnyWhere。
 
提示:每秒7帧,也就是142毫秒一帧,用TTimer足够,不过图像需要压缩,同时屏幕分辨率
也是个关键。技巧:HOOK 系统的WM_PAINT消息,只传送变化的部分(DX没试过)
 
关注!!!
 
llfirst:能够提供给我更详尽的方法吗?一些关键的地方还要劳你多多费心!
 
[^]我做过局域网计费软件,用过抓屏技术,
不压缩传送2帧/秒,压缩传送10帧/秒,
我可以考虑先给你演示程序。
我的email : bolvin@371.net
 
去http://www.uk.research.att.com/vnc/下载源代码(截屏,压缩,传输洋洋俱全)
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
顶部