hook gdi绘图API函数的方法或者差值传输图像的算法(200分)

  • 主题发起人 主题发起人 zhaokaien
  • 开始时间 开始时间
to appfirst
非常感谢!!结贴时会有小分相赠,笑纳!!
如果阁下能够贴出一些代码或你所说的详细的技巧,愿意给再100分!!
 
代码就不贴了,技巧可以简单说一下,算是抛石引路,比如在差异图像处理的时候,可以分关键帧与其他帧,这样可以减少比对的时间等。
 
分块和比较都很容易,如想速度快,这样是不理想的,因为当宽屏变化大的时候,压缩和传输都会很慢,在INTERNET更明显,比较图像可以用内存指针,得到两幅图的SCANLINE指针,时行比较内存即可得出一样否

procedure TScreenThread.MakeScreenData; //初始化操作

Function MultiRoot(ANumber, MaxRoot: Cardinal): Cardinal;
Begin
If MaxRoot>0 then
While (ANumber mod MaxRoot)<>0 do
MaxRoot:= MaxRoot-1;
Result:= MaxRoot;
End;

Var
i: Integer;
begin
If Isworking then
ReleaseScreenData;
Isworking:=True;
i:=Trunc(sqrt(FMaxBlockcount)); //开始计算block, X,Y方向最大块数;
BlockRowCount:=MultiRoot(Screen.Height,i); //高度分块
BlockHeight:=Screen.Height div BlockRowCount;
BlockColumnCount:=MultiRoot(Screen.Width,Trunc(FMaxBlockcount/BlockRowCount));
BlockWidth:=Screen.Width div BlockColumnCount;
BlockCount:=BlockColumnCount * BlockRowCount;
BlockBound:=Rect(0, 0, BlockWidth, BlockHeight);
SetLength(ScreenBitmaps, BlockCount); //开始创建screenbitmaps数组中所有元素
For i:=0 to BlockCount-1 do
Begin
ScreenBitmaps.Bound:=Rect(0,0,BlockWidth,BlockHeight);
OffsetRect(ScreenBitmaps.Bound, (i mod BlockColumnCount) * BlockWidth, (i div BlockColumnCount) * BlockHeight);
ScreenBitmaps.newbmp:=tmemorystream.Create;
ScreenBitmaps.LastScreen:=tmemorystream.Create;
End;
ScreenCanvas:=TCanvas.Create; //创建screencanvas画布
ScreenCanvas.Handle:= GetDC(0);
TempStream:=Tmemorystream.Create; //创建比较图片所用内存流
mytemp:=tmemorystream.Create; //创建发送数据所用内存流
BMP:=TBitmap.Create; //创建抓屏所用bmp
bmp.Width:=blockwidth;
bmp.Height:=blockheight;
fPixelFormat:=pf8bit; //设定默认色彩位数
try
i:=-1;
DataCom.Socket.Write(i);
DataCom.Socket.Write(screen.Width); //屏幕宽度
DataCom.Socket.Write(screen.Height); //屏幕高度
DataCom.Socket.Write(FMaxBlockcount); //分块长度
except
end;
end;

屏幕分块代码
 
线程代码

procedure TScreenThread.Execute;
Var
i,ScrW,ScrH:Integer;
begin
While (Terminated=false) and DataCom.Connected do //循环
Begin
If SBIndex=0 then
Begin
if (ScrW<>Screen.Width) and (ScrH<>Screen.Height) then //首次发送初始化信息
begin
ScrW:=Screen.Width;
ScrH:=Screen.Height;
MakeScreenData; //初始化
end; //跟踪抓屏
For i:=0 to BlockCount-1 do
With ScreenBitmaps do
If BMP.Canvas.TryLock then
try
bmp.PixelFormat:=FPixelFormat;
BMP.Canvas.CopyRect(BlockBound, ScreenCanvas, Bound);
newbmp.Clear;
bmp.SaveToStream(newbmp);
finally
BMP.Canvas.Unlock;
end;
inc(unit1.js);
end;

with ScreenBitmaps[SBIndex] do //比较 发送
If (newbmp.Size<>lastscreen.Size)or Not CompareMem(newbmp.Memory,LastScreen.Memory,LastScreen.Size) then
Begin
CompareStream(LastScreen,newbmp); //和上一幅比较
sendstream(SBIndex);
End;

SBIndex:= (SBIndex + 1) mod BlockCount; //循环
End;
end;
 
这是我以前作的一个程序,当然并不完全是原创代码,有一部分是SCREENSPY的,自己改进了一下,但还是不太理想,建设用视频勾子
如楼主想要DEMO留下MAIL我传给你
 
非常感谢hkcbz
我的邮箱是xyzw-0016@163.com
揭帖时小分相送,笑纳
 
我仔细的研究所screenspy.pas模块,是老外写的差异传输的组件,写的不错,但是实践有些问题是,一开始传输时屏幕会变花10-30秒左右,怎么样消除这一影响,我一直没有找到好地解决方案,我觉得加一个缓冲队列可能有帮助,具体还在实验中,另外传输的过程中也会偶尔出现小方块状的花屏状况,不过总的来说可以接受,大家有什么经验请不吝共享,大家一起提高
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部