改进:检测屏幕上像素的颜色并移动鼠标

时间:2016-08-23 17:45:19

标签: c# winforms

此代码由某人编写,此功能代码如下:

根据颜色像素位置可以找到并点击位置被发现,到目前为止,性能优秀但是这个代码有问题,快速找到位置并且颜色太低,大概是3秒(3000)需要。

是否可以提高速度或提高速度?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using System.Media;

namespace Login_Button_Click_for_Puzzle_Pirates
{
    public partial class frmMain : Form
    {
        [DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData,
          int dwExtraInfo);


        public enum MouseEventFlags : uint
        {
            LEFTDOWN = 0x00000002,
            LEFTUP = 0x00000004,
            MIDDLEDOWN = 0x00000020,
            MIDDLEUP = 0x00000040,
            MOVE = 0x00000001,
            ABSOLUTE = 0x00008000,
            RIGHTDOWN = 0x00000008,
            RIGHTUP = 0x00000010,
            WHEEL = 0x00000800,
            XDOWN = 0x00000080,
            XUP = 0x00000100
        }

        public frmMain()
        {
            InitializeComponent();
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {


            // takes a snapshot of the screen
            Bitmap bmpScreenshot = Screenshot();

            // makes the background of the form a screenshot of the screen
            this.BackgroundImage = bmpScreenshot;

            // find the color and check if it exists
            Point location;
            bool success = FindBitmap(Properties.Resources.bmpLogin, bmpScreenshot, out location);

            // check if it found the bitmap
            if (success == false)
            {
                MessageBox.Show("Couldn't find color!");
                return;
            }


            // move the mouse to location
           Cursor.Position = location;


            // click
            MouseClick();

        }

        /// <summary>
        /// Simulates a mouse click
        /// </summary>
        private void MouseClick()
        {
            mouse_event((uint)MouseEventFlags.LEFTDOWN, 0, 0, 0, 0);
            Thread.Sleep((new Random()).Next(20, 30));
            mouse_event((uint)MouseEventFlags.LEFTUP, 0, 0, 0, 0);
        }

        /// <summary>
        /// Takes a snapshot of the screen
        /// </summary>
        /// <returns>A snapshot of the screen</returns>
        private Bitmap Screenshot()
        {
            // this is where we will store a snapshot of the screen
            Bitmap bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);


            // creates a graphics object so we can draw the screen in the bitmap (bmpScreenshot)
            Graphics g = Graphics.FromImage(bmpScreenshot);

            // copy from screen into the bitmap we created
            g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);

            // return the screenshot
            return bmpScreenshot;
        }

        private bool FindBitmap(Bitmap bmpNeedle, Bitmap bmpHaystack, out Point location)
        {
            for(int outerX = 0; outerX < bmpHaystack.Width - bmpNeedle.Width; outerX++)
            {
                for (int outerY = 0; outerY < bmpHaystack.Height - bmpNeedle.Height; outerY++)
                {
                    for (int innerX = 0; innerX < bmpNeedle.Width; innerX++)
                    {
                        for (int innerY = 0; innerY < bmpNeedle.Height; innerY++)
                        {
                            Color cNeedle = bmpNeedle.GetPixel(innerX, innerY);
                            Color cHaystack = bmpHaystack.GetPixel(innerX + outerX, innerY + outerY);

                            if (cNeedle.R != cHaystack.R || cNeedle.G != cHaystack.G || cNeedle.B != cHaystack.B)
                            {
                                goto notFound;
                            }
                        }
                    }
                    location = new Point(outerX, outerY);
                    return true;
                notFound:
                    continue;
                }
            }
            location = Point.Empty;
            return false;
        }

        private void frmMain_Load(object sender, EventArgs e)
        {

        }
    }
}

1 个答案:

答案 0 :(得分:2)

是的,这可以更快地完成。 GetPixel是一个众所周知的缓慢功能。您需要锁定位图并检索原始像素数据,然后您可以搜索它寻找您正在寻找的颜色。

Stack Overflow还有其他答案提供示例,请参见此处: Bitmap.Lockbits confusion