龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > asp.net编程 >

C#实现获取屏幕图像差异效果(2)

时间:2009-12-21 11:47来源:未知 作者:admin 点击:
分享到:
C# Code [http://www.xueit.com] /// summary /// 查找出差异的块,调用该方法前请确认已经调用了InitalizeBlocks方法对所有块进行初始化 /// /summary /// param name="bmp" 目标图

C# Code [http://www.xueit.com]
/// <summary>
/// 查找出差异的块,调用该方法前请确认已经调用了InitalizeBlocks方法对所有块进行初始化
/// </summary>
/// <param name="bmp">目标图片</param>
/// <param name="cursorPoint">鼠标所在的坐标</param>
public void FindDifferences(Bitmap bmp, Point cursorPoint)
{
    if (cursorPoint.X >= _oldBmp.Width || cursorPoint.X < 0 || cursorPoint.Y >= _oldBmp.Height || cursorPoint.Y < 0)
    {
        return;
    }

    int cursorBlockIndex;
    int currentIndex;
    int blockTop;
    int blockLeft;
    BitmapData bdOldBmp;
    BitmapData bdNewBmp;
    Bitmap newBmpBlock;
    Rectangle rectBlock;

    cursorBlockIndex = (cursorPoint.X / _blockWidth)   (cursorPoint.Y / _blockHeight) * _blocksInRow;
    _isSupposedChanged[cursorBlockIndex] = true;
    _isScanned[cursorBlockIndex] = false;
    currentIndex = 0;
    
    unsafe
    {
        byte* pointerToOldBmp;
        byte* pointerToNewBmp;

        while (currentIndex < _blocks.Capacity)
        {
            if (!_isScanned[currentIndex] && _isSupposedChanged[currentIndex])
            {
                _isScanned[currentIndex] = true;
                blockTop = (currentIndex / _blocksInRow) * _blockHeight;
                blockLeft = (currentIndex % _blocksInRow) * _blockWidth;
                rectBlock=new Rectangle(blockLeft, blockTop, _blockWidth, _blockHeight);
                newBmpBlock = (Bitmap)bmp.Clone(rectBlock,_format);//克隆的时间需要0.015~0.016s左右
                rectBlock.X = 0;
                rectBlock.Y = 0;

                bdOldBmp = _blocks[currentIndex].LockBits(rectBlock, ImageLockMode.ReadWrite, _format);
                bdNewBmp = newBmpBlock.LockBits(rectBlock, ImageLockMode.ReadWrite, _format);
                
                int k = RtlCompareMemory(bdOldBmp.Scan0, bdNewBmp.Scan0, _blockWidth * 3 * _blockHeight);
                if (k < bdOldBmp.Stride * _blockHeight)
                {
                    pointerToOldBmp = (byte*)bdOldBmp.Scan0.ToPointer();
                    pointerToNewBmp = (byte*)bdNewBmp.Scan0.ToPointer();

                    for (int height = 0; height < _blockHeight; height  )
                    {
                        for (int width = 0; width < _blockWidth; width  )
                        {
                            pointerToOldBmp[0] = pointerToNewBmp[0];
                            pointerToOldBmp[1] = pointerToNewBmp[1];
                            pointerToOldBmp[2] = pointerToNewBmp[2];
                            pointerToNewBmp  = 3;
                            pointerToOldBmp  = 3;
                        }
                        pointerToNewBmp  = bdNewBmp.Stride - newBmpBlock.Width * 3;
                        pointerToOldBmp  = bdNewBmp.Stride - newBmpBlock.Width * 3;
                    }

                    if (currentIndex - _blocksInRow - 1 >= 0)
                    {
                        _isSupposedChanged[currentIndex - _blocksInRow - 1] = true;
                        _isSupposedChanged[currentIndex - _blocksInRow] = true;
                    }
                    else if (currentIndex - _blocksInRow >= 0)
                    {
                        _isSupposedChanged[currentIndex - _blocksInRow] = true;
                    }

                    if (currentIndex   _blocksInRow   1 < _blocks.Capacity)
                    {
                        _isSupposedChanged[currentIndex   _blocksInRow   1] = true;
                        _isSupposedChanged[currentIndex   _blocksInRow] = true;
                    }
                    else if (currentIndex   _blocksInRow < _blocks.Capacity)
                    {
                        _isSupposedChanged[currentIndex   _blocksInRow] = true;
                    }

                    if (currentIndex % _blocksInRow > 1)
                    {
                        _isSupposedChanged[currentIndex - 2] = true;
                        _isSupposedChanged[currentIndex - 1] = true;
                    }
                    else if (currentIndex % _blocksInRow > 0)
                    {
                        _isSupposedChanged[currentIndex - 1] = true;
                    }

                    if (currentIndex % _blocksInRow < _blocksInRow - 2)
                    {
                        _isSupposedChanged[currentIndex   2] = true;
                        _isSupposedChanged[currentIndex   1] = true;
                    }
                    else if (currentIndex % _blocksInRow < _blocksInRow - 1)
                    {
                        _isSupposedChanged[currentIndex   1] = true;
                    }

                    if (handler != null)
                    {
                        handler(newBmpBlock, rectBlock);
                    }
                }

                _blocks[currentIndex].UnlockBits(bdOldBmp);
                newBmpBlock.UnlockBits(bdNewBmp);
                currentIndex = Math.Max(Math.Min(currentIndex - _blocksInRow - 1, currentIndex - 2), 0);
            }
            else
            {
                currentIndex  ;
            }
        }//end of while
    }//end of unsafe
}//end of FindDifferences

注:该实现由于并不是特地为了实现屏幕传输,所以在比较的时候,我利用了Clone方式获取第二张图片的对应块。该方式需要耗时0.015s左右,因此比较100块图像就会额外使用1.5s左右的时间。
项目打包下载:http://files.cnblogs.com/stg609/Pic-v2-0.rar

作者:stg609
出处:http://stg609.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。


精彩图集

赞助商链接