This code is written by someone and this function code is as follows:
According to color pixel location can be found and click on position was found, so far, the performance is excellent but a problem with this code, quickly find the position and the color is too low that is about 3 second (3000) it takes.
Is it possible to be done to increase speed or speed improvement?
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)
{
}
}
}
Yes, this can be done faster. GetPixel
is a notoriously slow function. You need to lock the bitmap and retrieve the raw pixel data, then you can search it for the color you're looking for.
There are other answers on Stack Overflow which provide examples, see here: Bitmap.Lockbits confusion
User contributions licensed under CC BY-SA 3.0