新威客交易 IM
远程控制设计文档
文件状态:
[√] 草稿
[
[
] 正式发布
] 正在修改
文件标识: 新威客小组——远程控制设计
当前版本: 0.1
作
者: 陈 旭
完成日期:
新威客小组
浙江大学软件学院
版本/状态
作者
参与者
0.1
陈旭
版 本 历 史
起止日期
2010-05-12~
2010-5-14
备注
创建文档
目 录
1 文档介绍.................................................................................................................................... 4
1.1 文档目的 ................................................................................................................................ 4
2 远程控制概述............................................................................................................................ 5
3 屏幕传输.................................................................................................................................... 6
3.1 隔行方式概述 ........................................................................................................................ 6
3.2 隔行方式代码 ........................................................................................................................ 8
3.3 分块方式概述 ...................................................................................................................... 12
3.4 分块方式主要代码 .............................................................................................................. 14
4 实施控制.................................................................................................................................. 19
5 参考链接.................................................................................................................................. 20
1.1 文档目的
1 文档介绍
编写该文档的目的在于为远程控制的实现提供一个参考方案。
本项目中的远程控制即指通过某一客户端实现对另一客户端的鼠标、键盘的控制。远程
2 远程控制概述
控制主要由两在部分组成:屏幕传输、鼠标键盘控制。
下面通过两个章节来简单叙述下这两个内容。
屏幕传输即指将某一客户端的桌面通过某种算法以合适的速度显示在另一个客户端的
3 屏幕传输
界面上。
按照人眼的习惯,对于远程控制这种变化频率不高的应用,大致控制在每秒 5 帧的图片
切换速度可以实现基本流畅。如果能达到 10fps 以上,则已经是相当流畅了。
而要想提高 FPS 关键在于提高图片提取的速度以及网络传输的速度。对于后者,无非
就是选择 UDP 和 TCP 的问题。在传输速度上显然是 UDP 优于 TCP,但是在可靠性方面就
远远不如 TCP,如果能在 UDP 上实现自己的可靠传输,那么 UDP 是一个不错的选择。
而至于提取图片就有许多方法了。可以尝试全屏传输,也可以只取变化的部分。但是很
显然全屏传输相当消耗带宽。试想一下,以 1280*760
32 位色的桌面来举例,每秒传输 5
帧,那么一秒内传输的数据量为:1280*768*32*5=19200K 字节,大约 18.75M。一秒传
18.75M,这远远不是当前的带宽所能承受的。所以更好的是取变化的部分。目前业界获取
获取屏幕图片主要有如下几种方式:1.隔行扫描;2.分块比较;3.利用 mirror 驱动。
在实际开发中,发现隔行的效率不如分块效率来得高。至于 mirror 驱动的方式,并没
有进行研究。
3.1 隔行方式概述
翻阅了很多网上达人的文章,发现通常用于屏幕传输的方法主要是传输前后两幅图片的
不同之处。而查找不同之处的算法又主要有两类:隔行查找和分块比较。翻阅了很多,主要
是以 Delphi 下的实现为主,尤其以 DG 老大为代表的实现方式。由于本人从未用过 Delphi,
对 C++也有多年未用了,因此在研究 DG 老大的代码(DGScreenSpy_0.2c)上着实花了不少
时间,现在也只能算是懂了个基本。在我自己的实现方式,并非只是简单的对 DG 老大代码
的翻译,根据我自己的理解,我的算法思路如下:
首先对两张图片的数据按照从上到下从左到右的方式进行扫描,考虑到在实际的环境
下,一个图标或一个窗口肯定会横向和纵向跨好几个像素,因此用了两个参数来分别表示步
进值。扫描的过程中用一个矩形区域来表示当前变化的范围,这个范围在整个扫描过程中会
随时进行调整以适应变化的区域。
下面举个例子来说明区域的设置:从第 0 行开始扫描,没有发现该行内的像素不同,加
上步进的数值后(假如是 3),扫描接着从第 4(3+1)行开始,在该行的扫描中发现第 2 个
像素到第 10 个像素(基数为 0)都不同,于是设置矩形的 Top 边为 4,Left 为 2,Right 为
11,Bottom 为 5。接着扫描第 8 行,发现这一行中第 0 个像素到第 8 个像素不一样,则调整
矩形的区域(Top:4,Left:0,Right:11,Bottom:9),依次类推直到扫描到一行全都相同或扫描完
最后一行时,这个矩形的区域则正式确定。这样该区域的图形就是最小的变化范围。
这是大概的思路,具体的大家可以参考我的代码。按照这种方式,可以获取变化的最小
区域,如果变化不多,则图片数据量明显变少,如果变化很多或干脆整个屏幕都不一样,那
图片数据量仍然会很大,因此还需要进一步对图片数据进行压缩或采取降低图片颜色质量的
方式,QQ 的远程屏幕传输就降低了图片的质量,估计其图片质量为 16 位每像素。
为了专门研究图片差异的获取,所以并没有实现其他诸如压缩、传输的功能。其中对像
素的比较用的是 BitmapData.Scan0 来获取像素指针的方式进行比较,因为这样比较速度最
快。我在测试时发现,我的这种实现方式(以我设置的步进值为基准)一次比较需要 0.15
秒左右(包括了存储差异部分到本地文件的时间,大约耗时 0.04 秒),速度上仍然有待提升。
改变步进值可以适当的调节速度,但也会影响到变化区域的准确性。
图 1 软件界面图
图 2 差异结果图
图片说明:第一幅图展示的是我所实现的这个软件的最终效果图,通过菜单栏的按键可
以选择两幅有差异的图片(要求是相同大小,24 位或以上颜色,目的是模仿系统屏幕截图),
然后对图片进行比较后,就会截取出差异部分,并将该图片保存到硬盘中,也就是上面的差
异结果图。
3.2 隔行方式代码
public void FindDifferences()
{
if (_oldBmp.GetHashCode() == _newBmp.GetHashCode())
{
}
_status = -1;
return;
else if (_oldBmp.Width != _newBmp.Width || _oldBmp.Height != _newBmp.Height)
{
}
_status = 1;
return;
else
{
//行扫描
BitmapData bdOldBmp = _oldBmp.LockBits(new Rectangle(0, 0, _oldBmp.Width, _oldBmp.
Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bdNewBmp = _newBmp.LockBits(new Rectangle(0, 0, _newBmp.Width, _new
Bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int rectTop = -1, rectLeft = -1, rectRight = -1, rectBottom = -1;
int vStep = VERTICAL_STEP;