快元旦了,离上一次写日志也隔了挺久了(最近为了排练元旦晚会的小品耽搁了很久,嘿嘿)。明后天,打算去外地玩二三天,于是就想着在这之前把屏幕传输 v2.0先写了,以免拖太久了,我又懒得写了。
现来看下图吧:
图1 屏幕传输效果图
这张图可能并不能直观的表现出效果,不过拿来意思意思应该还是可以的。
开发环境:VS 2008 、WIN XP SP2、双核、集成显卡、1G内存
开发语言:CSharp
上一篇中,我分享的是在Dot Net环境下实现屏幕图像差异的获取,这次的实现主要就是基于这种思想来实现。不过为了适应屏幕传输的情况,做了些许修改。这些修改主要体现在以下几点:
1)不再存储图像的分块数据,而是存储一幅图片,然后定位到相应的分块位置后进行比较。
2)修改原三种假设如下:
在对一幅图片进行扫描时,首先认为鼠标所在区域为“最有可能变化的区域”(同上一篇),如果是第一次调用扫描方法,则认为第一行也是“最有可能变化区域”,然后对该幅图片的分块进行从左到右从上到下的扫描,如果被标记为“变化区域”,则进行比较。扫描的时候如果发现当前块没有发生变化,则将该块从“可能变化的区域”中移除。当第二次调用扫描算法时,则认为第二行是最有可能变化的区域,依此类推。如果达到最后一行,则重第一行开始轮回。
测试时遇到的主要问题:(申明:只做了各别的单元测试,并没有做具体的压力测试,测试环境也不具有代表性,因此,当前的实现尚不能保证其运行的稳定、可靠。而这些非功能需求,会在以后慢慢完善。)
问题描述:
本机(12寸Thinkpad本本、双核 P8400 、1G内存、集成显卡、分辨率 1280*800 32位色)试验,延迟基本在毫秒极,感觉比较流畅。但是拿到一联想品牌台式机(17寸 1280*1024 32位色、双核)试验,延迟陡然变大为秒级,感觉相当卡。原因:
问题出在分块截屏上。我原先采用的是对图像数据进行分块存储,然后每一次比较分块的时候,才截取该对应分块的当前屏幕图像数据(截屏用的是Graphic的CopyFromScreen方法),然后再比较。而这一步在我的本本上影响不明显,但是在17寸台式机上问题就显现出来了。最初,我以为是用CopyFromScreen方法截屏方法的效率不高,于是改用Bitblt这个API来截,但试验后发现效果几乎一致。你可以自己试下一次性截取1280*1024的图片速度和分128次截取128块图片数据(16*8块图片刚好组成这幅图片)速度,后者可以比前者慢上6~8倍。而且,图片数据越大,差距越明显(这也就是为什么我在我的12寸本本上没感觉出来,而在17寸上感觉出来的原因)。解决方案:
每一次进行一轮图像比较时,截取一次全屏的图像,然后对新截取的图像和原始图像数据进行分块定位比较。总结:
出现问题并不可怕,但这个问题暴露出自己在软件开发过程中的一个毛病,可能很多朋友曾经也和我一样走过这条路,那就是急于求成,对单元测试不放在心上。前期发现问题解决问题永远比后期发现问题解决问题所消耗的资源要少得多,在提交自己编写的代码前做好足够的单元测试是作为一个优秀软件开发人员的品质之一。
屏幕传输的基本流程:
当前这种实现方式还有许多不够完善的地方,比如长时间且大范围的变化,则会发现延迟会逐渐变大,另外对于大范围的变化其CPU占用率也比较高,这些都需要进一步来完善。下一步的工作,将对该实现进行完善并会加入控制功能。希望高手们多提意见~!
项目打包下载:http://files.cnblogs.com/stg609/ScreenShare-v2.0.rar