昨天介绍了被监控端的实现思路,今天我们来吧代码填了,我们严格按照昨天说的步骤来一一列出:
首先取到第一张截图:
List<Bitmap> _listfirst = new List<Bitmap>();//原图切割集合 List<Bitmap> _listsecond = new List<Bitmap>();//与原图作对比的图切割集合 Bitmap _bitfirst = null;//第一张截图(原图) List<Bitmap> _listzhongjian = new List<Bitmap>(16 * 9);//把屏幕分为16*9个小框 _bitfirst = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format16bppRgb555);
得到图后,我们分解它:
/// <summary> /// 初始化格子 /// </summary> private void Initial() { int top = 0; int left = 0; _kwidth = _bitfirst.Width / _rownum; _kheight = _bitfirst.Height / _coumunnum; for (int i = 1; i <= _listzhongjian.Capacity; i++) { top = ((i + _rownum - 1) / _rownum) - 1; left = i - _rownum * top - 1; _listfirst.Add((_bitfirst.Clone(new Rectangle(left * _kwidth, top * _kheight, _kwidth, _kheight), PixelFormat.Format16bppRgb555))); } }
得到分解格子后我们可以再截一张图来然后分成和上面一样多的格子然后作对比:下面是内存对比的API函数,我们的程序全靠它了
[DllImport("ntdll.dll")] private static extern int RtlCompareMemory(IntPtr Destination, IntPtr Source, int Length);
对比每个小格子的内存,下面是一段关键的代码,理清逻辑后可以自己去实现:
private void Diff() { int currentindex = 0; BitmapData newbmpdata; BitmapData oldbmpdata; Bitmap newbmpkuai; Rectangle rect; int kuaiTop; int kuaiLeft; Rectangle rect1 = new Rectangle(0, 0, _bitsecond.Width, _bitsecond.Height); Bitmap bitzhongjian = (Bitmap)_bitsecond.Clone(); Dictionary<Point, Bitmap> currbit = new Dictionary<Point, Bitmap>(); unsafe { Graphics gs = Graphics.FromImage(bitzhongjian); while (currentindex < _listzhongjian.Capacity) { kuaiTop = (currentindex / _rownum) * _kheight; kuaiLeft = (currentindex % _rownum) * _kwidth; rect = new Rectangle(kuaiLeft, kuaiTop, _kwidth, _kheight); newbmpkuai = (Bitmap)_bitfirst.Clone(rect, PixelFormat.Format16bppRgb555); rect.X = 0; rect.Y = 0; oldbmpdata = _listsecond[currentindex].LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format16bppRgb555);//表示当第二张图片前小方格的图像数据 newbmpdata = newbmpkuai.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format16bppRgb555);//表示当第一张图片前小方格的图像数据 int k = RtlCompareMemory(oldbmpdata.Scan0, newbmpdata.Scan0, _kwidth * _kheight * 2); bool f = false; if (k < oldbmpdata.Stride * _kheight)//对比后k值小于扫描内存范围视为不一致 { //一些所需操作 } } }
以上的代码不完全,读懂了就好了,因为我没有做线程的demo,操作部分的逻辑与当前内容无关,我就不贴出来了,当对比值k小于扫描范围时,你可以记录下第二张截图的不同部分小个子的序号,我们就能操作了
当然,想让程序活起来,我们可能需要做一个时间线程来连续的做以上事情的重复对比,
th = new System.Threading.Timer(new System.Threading.TimerCallback(截图到对比的方法), this, 0, 200);
这样子程序就算活了,监控端收到不同部分的图片后找到该位置,将小格子中的图片加进去就补充成一张新图跟新一下就OK了,以上部分是被监控端的主要代码,源码未分解出来,有空再整理下,因为没做demo,请多原谅。