Pet*_*ter 4 c# for-loop image visual-studio
当我使用下面的代码时,如果找不到我在图像中搜索的图像,则在完成循环之前大约需要3-5秒.当这是搜索时,程序的其余部分暂停,我的计时器不同步,看起来程序冻结了几秒钟.图像不是很大,"printscreen"约为344x354,"Ok"约为15x7.我知道这是因为for循环,但有没有更好的方法来做到这一点,或者我可以以某种方式除了程序的其余部分之外,他的程序部分,所以程序不会冻结几秒钟.
// Ok is the image I am searching for.
// printscreen is the image I am searching in.
Bitmap Ok = new Bitmap(Properties.Resources.popupok1);
int Count = 0;
for (int x = 0; x < printscreen.Width; x++)
{
for (int y = 0; y < printscreen.Height; y++)
{
Count = 0;
if (printscreen.GetPixel(x, y) == Ok.GetPixel(0, 0) &&
printscreen.GetPixel(x + 1, y) == Ok.GetPixel(1, 0))
{
for (int OkX = 0; OkX <= Ok.Width; OkX++)
{
for (int OkY = 0; OkY <= Ok.Height; OkY++)
{
try
{
if (printscreen.GetPixel(x + OkX, y + OkY) != Ok.GetPixel(OkX, OkY))
{
OkX = Ok.Width;
OkY = Ok.Height;
}
else
{
Count += 1;
}
if (Count == 105)
{
X = x;
Y = y;
OkX = Ok.Width;
OkY = Ok.Height;
x = printscreen.Width - 1;
y = printscreen.Height - 1;
Console.Add("Ok button found.");
Console.Add("");
ConsoleUpdate();
}
}
catch { }
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Dr.*_*ABT 11
性能问题是由GetPixels/SetPixels引起的,这是访问.NET位图中数据的一种非常慢的方式.相反,我会研究Bitmap.LockBits方法来获取指向位图的指针并直接操作数据.它会快一个数量级.
请参阅MSDN:
以下代码示例演示如何使用PixelFormat,Height,Width和Scan0属性; LockBits和UnlockBits方法; 和ImageLockMode枚举.此示例旨在与Windows窗体一起使用.要运行此示例,请将其粘贴到表单中,并通过调用LockUnlockBitsExample方法处理表单的Paint事件,并将e作为PaintEventArgs传递.
private void LockUnlockBitsExample(PaintEventArgs e)
{
// Create a new bitmap.
Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
// This code is specific to a bitmap with 24 bits per pixels.
int bytes = bmp.Width * bmp.Height * 3;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
// Set every red value to 255.
for (int counter = 2; counter < rgbValues.Length; counter+=3)
rgbValues[counter] = 255;
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
// Unlock the bits.
bmp.UnlockBits(bmpData);
// Draw the modified image.
e.Graphics.DrawImage(bmp, 0, 150);
}
Run Code Online (Sandbox Code Playgroud)
如果你想要更快,而不是复制数组,操纵它并将其复制回来,你可以使用不安全的指针对位图进行操作.在这种情况下,内部部分将更改如下:
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
// This code is specific to a bitmap with 24 bits per pixels.
int bytes = bmp.Width * bmp.Height * 3;
unsafe
{
byte* rgbValues = (byte*)ptr;
// Set every red value to 255.
for (int counter = 2; counter < bytes counter+=3)
rgbValues[counter] = 255;
}
// Unlock the bits.
bmp.UnlockBits(bmpData);
Run Code Online (Sandbox Code Playgroud)
请注意注意位图的PixelFormat.上面的例子假设它的每像素BGR为24位.实际上,许多位图都是BGRA(每像素32位),因此您需要按照每个像素的顺序修改蓝色,格力,红色,Alpha四个字节.
| 归档时间: |
|
| 查看次数: |
1386 次 |
| 最近记录: |