当前位置: 代码迷 >> C# >> 小妹请问根据图片找位置
  详细解决方案

小妹请问根据图片找位置

热度:299   发布时间:2016-05-05 05:23:27.0
小妹请教根据图片找位置
不知道C#有没有这个功能,根据图标找到它在屏幕的位置。

例如:我保存了一个“我的电脑”的图片。我运行程序,程序会自动找到“我的电脑”这个图标在电脑

上的位置,并把鼠标移动到那个位置。

不知道C#可以实现这个功能吗?
------解决思路----------------------
 /// <summary>
    /// 找图类
    /// </summary>
    class ImageFindPoint
    {
        static string dsa23 = "请务尝试破解,我们将上传您的资料至网警...";
        /// <summary>
        /// 找小图
        /// </summary>
        /// <param name="sourceBitmap">大图</param>
        /// <param name="partBitmap">小图</param>
        /// <param name="tolerantError">匹配度(0-255) 0为完全匹配</param>
        /// <param name="maxErrorPoints">错点数量</param>
        /// <returns>返回坐标</returns>
        private Point FindImage_(Bitmap sourceBitmap, Bitmap partBitmap, int tolerantError, int maxErrorPoints)
        {
            int w0 = sourceBitmap.Width, h0 = sourceBitmap.Height, w = partBitmap.Width, h = partBitmap.Height;
            var bmp1 = sourceBitmap.LockBits(new Rectangle(0, 0, w0, h0), ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
            var data1 = new byte[bmp1.Stride * bmp1.Height];
            Marshal.Copy(bmp1.Scan0, data1, 0, bmp1.Stride * bmp1.Height);
            sourceBitmap.UnlockBits(bmp1);
            var bmp2 = partBitmap.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
            var data2 = new byte[bmp2.Stride * bmp2.Height];
            Marshal.Copy(bmp2.Scan0, data2, 0, bmp2.Stride * bmp2.Height);
            partBitmap.UnlockBits(bmp2);
            int[] rgb = { 2, 1, 0 };
            equals_ equals = new equals_(delegate(Point pt1_, Point pt2_)
            {
                int p1 = pt1_.Y * bmp1.Stride + pt1_.X * 4, p2 = pt2_.Y * bmp2.Stride + pt2_.X * 4;
                return AllCompleted(rgb, data1, data2, p1, p2, tolerantError);
            });
            ptRP ptRP_ = new ptRP(delegate(int x_, int y_) { return new Point(x_, y_); });
            var keyPts = new[] { ptRP_(0, 0), ptRP_(w - 1, 0), ptRP_(w / 2, h / 2), ptRP_(0, h - 1), ptRP_(w - 1, h - 1) };
            isMatch_ isMatch = new isMatch_(delegate(Point p0_)
            {
                if (AnyCompleted(keyPts, p0_, equals))
                    return false;
                int tolerant = maxErrorPoints;
                for (int y = 0; y < h; y++)
                    for (int x = 0; x < w; x++)
                        if (!equals(p0_ + (Size)ptRP_(x, y), ptRP_(x, y)) && (tolerant-- <= 0))
                            return false;
                return true;
            });
            for (int y = 0; y < h0 - h; y++)
                for (int x = 0; x < w0 - w; x++)
                    if (isMatch(ptRP_(x, y)))
                        return ptRP_(x, y);
            return ptRP_(-1, -1);
        }

        delegate bool equals_(Point pt1, Point pt2);
        delegate Point ptRP(int x_, int y_);
        delegate bool isMatch_(Point p);
        private bool AllCompleted(int[] rgbints, byte[] data1, byte[] data2, int p1, int p2, int tolerantError)
        {
            foreach (int i in rgbints)
                if (!(Math.Abs(data1[p1 + i] - data2[p2 + i]) <= tolerantError))
                    return false;
            return true;
        }
        private bool AnyCompleted(Point[] keyPts, Point p0_, equals_ equals)
        {
            foreach (Point i in keyPts)
                if (!equals(i + (Size)p0_, i))
                    return true;
            return false;
        }
        /// <summary>
        /// 在大图指定位置找小图 (记得范围+ - 5px)
        /// </summary>
        /// <param name="sourceBitmap">大图</param>
        /// <param name="partBitmap">小图</param>
        /// <param name="rc">指定范围(必须比小图大)</param>
        /// <param name="tolerantError">匹配度(0-255) 0为完全匹配</param>
        /// <param name="maxErrorPoints">错点数量</param>
        /// <returns>返回坐标</returns>
        public Point FindImage(Bitmap sourceBitmap, Bitmap partBitmap,Rectangle rc, int tolerantError, int maxErrorPoints)
        {
            try
            {
                Bitmap TempsourceBitmap = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top);
                Graphics gr = Graphics.FromImage(TempsourceBitmap);
                gr.DrawImage(sourceBitmap, 0, 0, new RectangleF(rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top), GraphicsUnit.Pixel);
                gr.Dispose();

                Point p = FindImage_(TempsourceBitmap, partBitmap, tolerantError, maxErrorPoints);



                if (p.X == -1)
                    return p;
                else
                {
                    if (p.X < 0 
------解决思路----------------------
 p.X > rc.Width 
------解决思路----------------------
 p.Y < 0 
------解决思路----------------------
 p.Y > rc.Height)
                        return new Point(-1, -1);
                    else
                        return new Point(p.X + rc.Left, p.Y + rc.Top);
                }
            }
            catch { return new Point(-1, -1); }
        }
        /// <summary>
        /// 在大图相对位置找小图 (记得范围+ - 5px)
        /// </summary>
        /// <param name="sourceBitmap">大图</param>
        /// <param name="partBitmap">小图</param>
        /// <param name="rc">指定范围(必须比小图大)</param>
        /// <param name="tolerantError">匹配度(0-255) 0为完全匹配</param>
        /// <param name="maxErrorPoints">错点数量</param>
        /// <returns>返回坐标</returns>
        public Point FindImageR(Bitmap sourceBitmap, Bitmap partBitmap, Rectangle rc, int tolerantError, int maxErrorPoints)
        {
            try
            {
                Bitmap TempsourceBitmap = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top);
                Graphics gr = Graphics.FromImage(TempsourceBitmap);
                gr.DrawImage(sourceBitmap, 0, 0, new RectangleF(rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top), GraphicsUnit.Pixel);
                gr.Dispose();

                Point p = FindImage_(TempsourceBitmap, partBitmap, tolerantError, maxErrorPoints);

                if (p.X == -1)
                    return p;
                else
                    return new Point(p.X, p.Y);
            }
            catch { return new Point(-1, -1); }
        }
        /// <summary>
        /// 在大图指定范围位置找小图
        /// </summary>
        /// <param name="sourceBitmap">大图</param>
        /// <param name="partBitmap">小图</param>
        /// <param name="tolerantError">匹配度(0-255) 0为完全匹配</param>
        /// <param name="maxErrorPoints">错点数量</param>
        /// <returns></returns>
        public Point FindImage(Bitmap sourceBitmap, Bitmap partBitmap, int tolerantError, int maxErrorPoints)
        {
            try
            {
                Point p = FindImage_(sourceBitmap, partBitmap, tolerantError, maxErrorPoints);
                return p;
            }
            catch { return new Point(-1, -1); }
        }



        /// <summary>        
        /// 比较两张图片是否完全一样        
        ///         
        /// 速度慢,但匹配精确        
        ///         
        /// (方法:匹配两张图片的每一个像素)        
        /// </summary>                
        private bool ImageCompareArray(Bitmap firstImage, Bitmap secondImage)        
        {            
            bool flag = true;            
            string firstPixel;            
            string secondPixel;            
            if (firstImage.Width == secondImage.Width && firstImage.Height == secondImage.Height)            
            {                
                for (int i = 0; i < firstImage.Width; i++)                
                {                   
                    for (int j = 0; j < firstImage.Height; j++)     
                    {                    
                        firstPixel = firstImage.GetPixel(i, j).ToString();   
                        secondPixel = secondImage.GetPixel(i, j).ToString();      
                        if (firstPixel != secondPixel)                   
                        {                    
                            flag = false;
                            break;        
                        }               
                    }           
                }            
                if (flag == false)        
                {               
                    return false;       
                }             
                else        
                {           
                    return true;       
                }         
            }         
            else        
            {        
                return false;  
            }      
        }      
        /// <summary>       
        ///  比较两张图片是否完全一样    
        ///  ///      
        ///  /// 速度快,但对大图片可能有些误差    
        ///  ///      
        ///  /// (方法:将图片转换为Base64后,匹配Base64)    
        /// </summary>    
        public bool ImageCompareString(Bitmap firstImage, Bitmap secondImage)  
        {
            if (firstImage == null)
                return false;
            MemoryStream ms = new MemoryStream();   
            firstImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);  
            String firstBitmap = Convert.ToBase64String(ms.ToArray());       
            ms.Position = 0;      
            secondImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);     
            String secondBitmap = Convert.ToBase64String(ms.ToArray());      
            if (firstBitmap.Equals(secondBitmap))       
            {     
                return true;     
            }         
            else   
            {          
                return false;   
            }   
        }





    }


给你代码  你也不一定能理解。
------解决思路----------------------
class ImageGet
    {
        static IntPtr dc1 = IntPtr.Zero;
        static IntPtr dc2 = IntPtr.Zero;
        static IntPtr dc3 = IntPtr.Zero;
        static Bitmap MyImage = null;
        /// <summary>
        /// 截取模拟器客户区图片
        /// </summary>
        /// <param name="hwnd">句柄</param>
        /// <returns></returns>
        public static Bitmap GetImgDesk(IntPtr hwnd)
        {
            ks:
            try
            {
                if (hwnd == IntPtr.Zero)
                {
                    return null;
                }
                SystemApi.RECT rc = new SystemApi.RECT();
                SystemApi.GetWindowRect(hwnd, out rc);
                SystemApi.PointApi p = new SystemApi.PointApi();
                SystemApi.ScreenToClient(hwnd, out p);
                //设置客户区的坐标
                SimulatorInfo.MainClientLack = new Point(Math.Abs(p.x) - rc.left, Math.Abs(p.y) - rc.top);

                SystemApi.RECT rcc = new SystemApi.RECT();
                SystemApi.GetClientRect(hwnd, out rcc);
                dc1 = SystemApi.CreateDC("DISPLAY", null,
                    null, (IntPtr)null);
                //创建显示器的DC
                Graphics g1 = Graphics.FromHdc(dc1);
                //由一个指定设备的句柄创建一个新的Graphics对象
                MyImage = new Bitmap(rcc.right, rcc.bottom, g1);
                //根据屏幕大小创建一个与之相同大小的Bitmap对象
                Graphics g2 = Graphics.FromImage(MyImage);
                //获得屏幕的句柄
                dc3 = g1.GetHdc();
                //获得位图的句柄
                dc2 = g2.GetHdc();
                //把当前屏幕捕获到位图对象中
                SystemApi.BitBlt(dc2, 0, 0, rcc.right,
                    rcc.bottom,
                    dc3, Math.Abs(p.x), Math.Abs(p.y), 13369376);
                //把当前屏幕拷贝到位图中
                g1.ReleaseHdc(dc3);
                //释放屏幕句柄
                g2.ReleaseHdc(dc2);
                //释放位图句柄
                g1.Dispose();
                g2.Dispose();
                return MyImage;
            }
            catch { MessageBox.Show("软件运行过程中,请勿关闭或最小化模拟器!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            hwnd= tdb.SimulatorInfo.MainHwnd;
            Thread.Sleep(500);
            goto ks; }
        }
        #region 截取模拟器客户区指定范围保存图片
        public static string a = "abcdefjhijklmnopqrstuvwxyz0123456789";
        /// <summary>
        /// 截取模拟器客户区指定范围保存图片
        /// </summary>
        /// <param name="hwnd">句柄</param>
        /// <param name="ec">截取范围</param>
        /// <returns></returns>
        public static Bitmap GetImgDesk(IntPtr hwnd, Rectangle ec)
        {
            SystemApi.RECT rc = new SystemApi.RECT();
            SystemApi.GetWindowRect(hwnd, out rc);
            SystemApi.PointApi p = new SystemApi.PointApi();
            SystemApi.ScreenToClient(hwnd, out p);
            dc1 = SystemApi.CreateDC("DISPLAY", null,
                null, (IntPtr)null);
            //创建显示器的DC
            Graphics g1 = Graphics.FromHdc(dc1);
            //由一个指定设备的句柄创建一个新的Graphics对象
            MyImage =
                new Bitmap(ec.Width, ec.Height, g1);
            //根据屏幕大小创建一个与之相同大小的Bitmap对象
            Graphics g2 = Graphics.FromImage(MyImage);
            //获得屏幕的句柄
            dc3 = g1.GetHdc();
            //获得位图的句柄
            dc2 = g2.GetHdc();
            //把当前屏幕捕获到位图对象中
            SystemApi.BitBlt(dc2, 0, 0, ec.Width, ec.Height,
                dc3, ec.X + Math.Abs(p.x), ec.Y + Math.Abs(p.y), 13369376);
            //把当前屏幕拷贝到位图中
            g1.ReleaseHdc(dc3);
            //释放屏幕句柄
            g2.ReleaseHdc(dc2);
            //释放位图句柄
            g1.Dispose();
            g2.Dispose();
            return MyImage;
        }

        #endregion

    }



句柄传桌面句柄即可。想要又快有准。哪有这么好的事。
如果你只是想获取桌面有哪些图标。然后打开相应的程序。这个自然不需要找图。 
不找图效率就很高。


如果你是新手。就不要随便例如。应该说 我现在想做什么功能。我想用找图方法。
如果别人认为用找图方法合适。自然会给你代码。
如果不合适。人家会告诉你怎么做合适。
所以  不要自认为自己例如得很好。 建议你把你要做的东西说出来。让大家看看
  相关解决方案