这里举例说明一下 A图是原图 B图是从A图上截下来的一部分
有什么办法能获得B图在A图上的起始坐标呢?如何对比2个图片的差异度 完全相同= 100% 完全不同 = 0% 

解决方案 »

  1.   

    这个是完全匹配的寻找坐标.. 颜色完全一样... 不支持溶差方式..
     public static Point GetImageContains(Bitmap p_SourceBitmap, Bitmap p_PartBitmap)
            {
                int _SourceWidth=p_SourceBitmap.Width;
                int _SourceHeight =p_SourceBitmap.Height;            int _PartWidth = p_PartBitmap.Width;
                int _PartHeight = p_PartBitmap.Height;            Bitmap _SourceBitmap = new Bitmap(_SourceWidth, _SourceHeight);
                Graphics _Graphics = Graphics.FromImage(_SourceBitmap);
                _Graphics.DrawImage(p_SourceBitmap, new Rectangle(0, 0, _SourceWidth, _SourceHeight));
                _Graphics.Dispose();
                BitmapData _SourceData = _SourceBitmap.LockBits(new Rectangle(0, 0, _SourceWidth, _SourceHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                byte[] _SourceByte = new byte[_SourceData.Stride * _SourceHeight];
                Marshal.Copy(_SourceData.Scan0, _SourceByte, 0, _SourceByte.Length);  //复制出p_SourceBitmap的相素信息             Bitmap _PartBitmap = new Bitmap(_PartWidth, _PartHeight);
                _Graphics = Graphics.FromImage(_PartBitmap);
                _Graphics.DrawImage(p_PartBitmap, new Rectangle(0, 0, _PartWidth, _PartHeight));
                _Graphics.Dispose();
                BitmapData _PartData = _PartBitmap.LockBits(new Rectangle(0, 0, _PartWidth, _PartHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                byte[] _PartByte = new byte[_PartData.Stride * _PartHeight];
                Marshal.Copy(_PartData.Scan0, _PartByte, 0, _PartByte.Length);   //复制出p_PartBitmap的相素信息             int _SourceIndex =0;
              
                for (int i = 0; i != _SourceHeight; i++)
                {
                    if (_SourceHeight - i < _PartHeight) return new Point(-1, -1);  //如果 剩余的高 比需要比较的高 还要小 就直接返回
                    string _SourceRowText = BitConverter.ToString(_SourceByte, _SourceIndex, _SourceData.Stride);  //获取行信息
                    int _PartIndex =0;   //定义比较需要读的开始位置
                    int _PointX = -1;    //临时存放坐标 需要包正找到的是在一个X点上
                    bool _SacnOver = true;   //是否都比配的上
                    for (int z = 0; z != _PartHeight; z++)       //循环目标进行比较
                    {
                        string _PartRowText = BitConverter.ToString(_PartByte, _PartIndex, _PartData.Stride);  //获取目标的行数据
                        int _TrueX = _SourceRowText.IndexOf(_PartRowText);   //获取当前坐标的位置
                        if (_TrueX == -1)   //如果没找到 
                        {
                            _PointX = -1;    //设置坐标为没找到
                            _SacnOver = false;   //设置不进行返回
                            break;  
                        }
                        else
                        {
                            if (z == 0) _PointX = _TrueX;
                            if (_PointX != _TrueX)   //如果找到了 也的保证坐标和上一行的坐标一样 否则也返回
                            {
                                _PointX = -1;//设置坐标为没找到
                                _SacnOver = false;  //设置不进行返回
                                break;
                            }
                        }
                        _PartIndex += _PartData.Stride;  //设定下一循环要读的坐标
                        int _SourceMoveRowIndex =_SourceIndex + ((z + 1) * _SourceData.Stride);                    _SourceRowText = BitConverter.ToString(_SourceByte, _SourceMoveRowIndex, _SourceData.Stride);  //获取源行信息
                    }                if (_SacnOver) return new Point(_PointX/3, i);
                    _SourceIndex += _SourceData.Stride;   //设定下一循环要读的坐标
                }      
                return new Point(-1, -1);
            }
      

  2.   


    测试过了吗?             Bitmap bmp = new Bitmap(Image.FromFile(@"C:\test\123.bmp"));            Bitmap bmp2 = bmp.Clone(new Rectangle(20, 20, 50, 50), bmp.PixelFormat);            Point p = GetImageContains(bmp,bmp2);
                MessageBox.Show("x=" + p.X + " y=" + p.Y);这样调用 返回的x y 都是-1.........
      

  3.   

    我想你还要加入图片的限制条件。
    如果A图是纯色的,那你说B图是从A图哪个地方拷贝出来的?
      

  4.   

       Bitmap SourceBitmap = (Bitmap)Image.FromFile(@"c:\1.BMP");            Bitmap bmp2 = SourceBitmap.Clone(new Rectangle(20, 20, 50, 50), SourceBitmap.PixelFormat);       
                MessageBox.Show(GetImageContains(SourceBitmap, bmp2).ToString());            
    我返回的结果是 80 20 改了下忘记了坐标要/3再/4 
    if (_SacnOver) return new Point(_PointX/3/4, i);
      

  5.   

    对了忘记说了 p_PartBitmap宽和高 都不能大于p_SourceBitmap