My goal is to be able to take a row of 70 pixels, analyze all 70 pixels for a certain kind of color, and then throw to another function if criteria are met. This needs to happen at least once every 50 milliseconds, and preferably even faster than that.
My current code looks like so
public void CaptureArea()
{
using (Bitmap capture = new Bitmap(70, 35))
{
using (Graphics g = Graphics.FromImage(capture))
{
for (int i = 0; i < 10; i++)
{
g.CopyFromScreen(copyPoint, pastePoint, new Size(70, 35));
evaluteBitmap(capture);
}
}
}
}
public void evaluteBitmap(Bitmap scanArea)
{
Rectangle rect = new Rectangle(0, 0, 70, 35);
BitmapData data = scanArea.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
IntPtr ptr = data.Scan0;
int bytes = data.Stride * scanArea.Height;
byte[] rgbValues = new byte[bytes];
byte[] r = new byte[bytes / 3];
byte[] g = new byte[bytes / 3];
byte[] b = new byte[bytes / 3];
Marshal.Copy(ptr, rgbValues, 0, bytes);
int count = 0;
int stride = data.Stride;
for (int column = 0; column < 30; column++)
{
b[count] = (byte)(rgbValues[(column * stride) + (34 * 3)]);
g[count] = (byte)(rgbValues[(column * stride) + (34 * 3) + 1]);
r[count++] = (byte)(rgbValues[(column * stride) + (34 * 3) + 2]);
}
scanArea.UnlockBits(data);
}
Just CaptureArea() can drop about 60 bitmaps into memory every second, which is fine, but it currently takes about 600 milliseconds for EvaluateBitmap() to grab a pixel and split it out into RGB values 70 times.
The end result is that a single frame of data takes well over 500 milliseconds to process when it needs to be much closer to 50 milliseconds. This kind of problem-solving is beyond me and I'm not experienced enough with code of this nature to be able to eyeball solutions and know what will end up being faster or slower and by how much.
Is there a way I can get performance quicker by an order of magnitude or am I asking the impossible?
Profiling session for the given code gives an unambiguous result:
CopyFromScreen - 40.00% exclusive samples
Bitmap..ctor - 15.00% exclusive samples
clr.dll - 11.67% exclusive samples
KernelBase.dll - 8.33% exclusive samples
GdiPlus.dll - 6.67% exclusive samples
LockBits - 6.67% exclusive samples
Image.Dispose - 5.00% exclusive samples
....
....
EvaluateBitmap - 1.67% exclusive samples
....
....
CaptureArea - 0.0% exclusive samples
The biggest portion of the time is spent on .NET methods which cannot be improved.
Conclusion: there no possible significant improvement of the code. You can probably use multithreading to process more frames during the given time period, though.