远程屏幕图象实时传输的原理与实现

远程屏幕图象实时传输的原理与实现
摘要:本文就当前的热点远程屏幕图象的抓取及其在网络上传输过程进行了详细介绍,并针对目前这类相关软件中普遍存在的网络带宽过大、实时性差、占用系统资源过多、稳定性差等问题侧重在屏幕图象的抓取与位图数据流的压缩、解压缩两方面提出了较为有效的解决方法,并提供了改进与实现的Delphi代码。本文将对于现有此类相关软件的完善及今后相关软件的研发具有非常重要的指导与参考价值。
关键词:屏幕图象 屏幕抓取 实时传输 网络传输 数据压缩
一、 前言
目前,随着计算机网络的不断推广运用,基于计算机网络的应用软件的研发也就成了众多的软件企业与科研机构的主要研发热点之一。在这些应用软件当中,基于计算机网络的远程实时控制、管理软件因其具有极其广泛的应用领域如网络多媒体教室、网络管理与控制、网络服务、在线技术支持等,所以它具有有非常良好的发展前景与商业价值。虽然目前已经有一些相关的软件产品,但普遍都存在占用网络带宽过大、实时性差、占用系统资源过多、稳定
性差等问题,究其原因就在于在远程屏幕图象在网络上传输这个关键技术环节上问题解决的不够理想。
本人经过长期的反复研究与实践,终于到了一些方法能够很好地解决远程屏幕图象网络传输占用网络带宽过大、实时性差、占用系统资源过多、稳定性差等关键问题,为这类软件研发中的远程屏幕图象在网络上传输提供一种非常有价值的可供参考的解决方法,以下便就此展开叙述与探讨。
二、 远程屏幕图象在网络上传输过程
一般这类软件都采用典型的Client/Server结构,由客户端与服务端两部分构成。客户端主要是负责向服务端发出获取服务端屏幕图象的请求与将从服务端发送而来的屏幕图象在本地实时地显示出来,而服务端主要是负责响应客户端的请求并抓取与发送屏幕图象。由于服务端所抓取的屏幕图象一般为位图格式,其数据量较大,若直接发送则会导致占用网络带宽过大、实时性差、占用系统资源过多、稳定性差等问题,因此需经过压缩后才能将其发送给客户端,而客户端相应地也要将接受到到屏幕图象数据进行解压缩后才能正确地将屏幕图象显示出来。
解决目前普遍存在的问题的关键就在于屏幕图象数据的压缩与解压缩和屏幕图象的抓取上。对于屏幕图象数据的压缩与解压缩这一点,主要追求的是较高的压缩率与较快的压缩与解压缩速度,这可以通过选取一定的压缩与解压缩算法如Huffman、RLE、LZW等来实现,已有的这类软件也非常注重这一点,因此目前这一方面的提高余地已非常有限。对于屏幕图象的抓取这一点,很多这类软件在研发过程中却不够注意甚至是忽略了所选取的屏幕图象抓取方法的重要性,而采用了常用的一般的抓取方法。其实,屏幕图象的抓取与数据的压缩与解压缩一样重要,都将对屏幕图象的实时传输过程产生极其重要的影响,因此这一方面尚有较大的提高空间,本文也就此着重进行详细的阐述。
三、 屏幕抓取与传输方法及其改进实现
1. 屏幕抓取模式的选择
屏幕抓取模式有多种,如在Delphi中可用的抓取模式CopyMode有cmSrcCopy、cmSrcInvert、cmWhiteness等15种。当采用cmSrcCopy模式时,则直接将待拷贝的源位图拷贝至目的画布中,目前普遍的处理方式便是采用这种抓取模式抓取整个屏幕图象,然后直接将其进行压缩。而若采用cmSrcInvert模式时,在服务端则先将目的画布中已有的位
图与待拷贝的源位图位值进行XOR异或运算后,然后将运算所得的位图进行压缩,相应地在客户端显示时,应将解压后的位图位值与当前的位图位值进行XOR异或运算,则运算所得的位图便是服务端当前所传送的屏幕图象。虽然后一种屏幕图象抓取方法比前一种分别在客户端与服务端多了一步位图位值XOR异或运算,但是经压缩后,采用后一种方法数据量一般比前一种方法的数据量要小得多。这主要是因为一般情况下屏幕图象总是在一个局部而非整个屏幕发生变化,将当前屏幕图象与上一屏幕图象进行XOR异或运算后,所得屏幕位图未变化部分的位值将为0,而变化部分的位值为1,当屏幕图象变化范围较小时,则所抓取的屏幕图象位图的大量位值将为0,同时压缩率除与压缩算法有关外,还与待压缩的数据本身有关,因此这样对其进行压缩将取得更加理想的压缩效果。 虽然采用两种抓取模式所获得的屏幕图象数据都一样,但从采用采用WinZip压缩后的数据量来看,cmSrcInvert 模式下的压缩数据量明显小于采用cmSrcCopy模式的压缩数据量。本人在测试时使用的是Delphi5.0中自带的一个数据流压缩、解压缩解决方案Zlib.pas和 Zlibconst.pas两个单元文件来解决数据压缩、解压缩问题,实现了很高的数据压缩率(较WinZip高),所得的测试结果也与上表的结果相近。这就说明采用cmSrcInvert 模式将比采用cmSrcCopy模式在传输屏幕图象数据时占用少得多的网络带宽。
在Delphi中的采用cmSrcInvert 模式抓取屏幕图象的实现程序代码如下:
…………………………..
dnf王刚var
bmp, difbmp: TBitmap;//两个用于保存屏幕图象的临时位图对象
R : TRect;//用于保存抓取范围的一个Trect对象
tmp : string;//用于保存压缩后的数据的变量
…………………..
CatchScreen(bmp, PixelFormat);//按指定的PixelFormat抓取全屏并将其存放于bmp中
difbmp := TBitmap.Create;
difbmp.Assign(bmp);//将bmp中的位图传递给difbmp
R := Rect(0, 0, difbmp.Width, difbmp.Height);//指定拷屏范围
difbmp.Canvas.CopyMode := cmSrcInvert;//设置拷贝模式为cmSrcInvert,非常重要
difbmp.Canvas.CopyRect(R, CurBmp.Canvas, R);//将当前图象与上一次的图象进行//XOR运算,将结果位图存放于difbmp中,其中CurBmp是一个全局变量,存放 //的是上一次抓屏时的屏幕图象
CompressBitmap(difbmp, tmp);//将difbmp进行压缩,压缩后的数据存放于tmp中
CurBmp.Assign(bmp);//当前图象存入CurBmp,下一次抓屏时进行XOR运算使用
…………………………………
屏幕图象抓取过程CatchScreen的实现代码如下:
procedure GetScreen(var bmp: TBitmap; PixelFormat: TpixelFormat);
var
dc : integer;
c : TCanvas;
R : TRect;
begin
bmp := TBitmap.Create;
dc := GetWindowDC(0);//获取整个屏幕的 DC,参数0指的是屏幕
广州大学城论坛try
c := TCanvas.Create; //创建一个canvas对象
c.Handle := dc;
R := Rect(0, 0, Screen.Width, Screen.Height);//指定抓取范围,采用的是全屏冷轧钢管
bmp.Width := R.Right;
bmp.Height := R.Bottom;
bmp.Canvas.CopyRect(R, c, R); //把整个屏幕复制到bmp中
bmp.PixelFormat:=PixelFormat;//设置位图格式
c.Handle := 0;
c.Free;
finally
ReleaseDC(0, dc);STUDYON
end;
end;
2. 屏幕分区域抓取与传输
目前一般都采用的是一次性整屏抓取,由于数据量大,往往无法取得较好的实时效果,尤其是在网络带宽有限时这一点特别突出。其实,服务端完全可以通过将屏幕划分为一定数
量的大小相等的矩形分别在抓取模式为cmSrcInvert下进行抓取与压缩,然后将压缩后的数据添加到一个待发送的队列中去等待传输。或者是比较所抓取的矩形区域图象是否发生了变化,若未发生变化则不处理,否则才进行后续处理。与此相对应,客户端从接受到的数据队列中取出队头数据进行解压,然后在相应位置上显示出一个矩形大小的图象。考虑到实时性要求,实际编程实现时可采用多线程程序设计,利用多个线程分别处理不同区域的屏幕图象。这种方法能够在不同的网络带宽情况下均获得较好的实时性,占用系统资源也较少,而且也会使软件的稳定性增强。但是必须要注意的是屏幕划分区域的个数应根据实际情况主要是网络带宽来设定,因为若划分区域的个数过多则会导致对每个矩形区域图象进行抓取、压缩、传输、解压和显示的时间总和反而超过整屏处理的时间,这样虽然网络带宽占用小,但实时性可能下降。又若划分区域的个数过少,则较整屏处理占用的网络带宽下降幅度不大,效果不明显。经过本人测试,在10M的局域网中划分区域的个数为4~6个时效果较为理想,此时每个矩形区域图象的数据经压缩后为1~2KB(分辨率800*600,增强16位),比采用整屏处理时的占用的网络带宽要低得多,而且实时性也有一定的提高,延迟低于0.8秒。
服务端:1. 抓取一个个矩形区域的屏幕图象;2. 判断矩形区域图象是否改变;3. 对发生改
赛内加尔
变的矩形区域图象进行压缩,并放入发送队列;4. 跳转到第1步。
客户端:1. 从接收队列中取出一个数据块2. 解压数据块,确定矩形区域位置3. 在指定位置显示矩形区域图象
4. 跳转到第1步
实际实现时,可用下列的数据结构来存储每个矩形区域图象的数据:
TYPE PNext=^GdiRect;
GdiRect=RECORD
X1,Y1,X2,Y2:Integer;//保存矩形左上角与右下角的坐标
Bitmap:TBitmap;//保存所抓取的屏幕图象
PixelFormt:TpixelFormat;//保存所抓取的屏幕位图的位值格式
收容教养制度退出历史舞台
CompressionLevel:TcompressionLevel;//保存压缩级别
Changed:Boolean;//保存该矩形区域的屏幕图象是否发生变化
GdiRectNext:PNext;//指向对列中下一个数据块的指针
………….;//根据需要所添加的其他一些变量
…………… ;
END;
四、 屏幕图象数据流的压缩与解压缩
对于所抓获的屏幕图象数据的压缩与解压缩可以选用多种算法如Huffman、RLE、LZW等第三方提供的解决方法,其实Delphi5.0本身就自带了一个非常优秀的数据流压缩、解压缩的控件包Zlib,可以利用其中的Zlib.pas和 Zlibconst.pas两个单元文件提供的接口来使用其中的方法。具体实现的思路如下:首先利用屏幕拷贝捕捉到当前整个屏幕的图像,然后在内存中保存为 BMP文件格式。在服务端进行压缩时,使用 TCompressionStream对象对原始图像进行压缩并且保存为自定义的变量中;在客户端解压缩时,使用 TDecompressionS
tream对象对被压缩的图像进行解压缩,还原为 BMP格式的图像文件并随即显示出来。压缩与解压缩具体实现的代码如下:

本文发布于:2024-09-23 22:26:04,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/320661.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:图象   屏幕   压缩   抓取
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议