昨天介紹了被監控端的實現思路,今天我們來吧代碼填了,我們嚴格按照昨天說的步驟來一一列出:
首先取到第一張截圖:
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,請多原諒。