So I’m writing an app to automate some gameplay elements of a rhythm game (and for those curious, I’ve already beaten it, so this is more of a programming challenge rather than a cheat tool). I’ve got it working in general, but the issue I’m having is that the screenshots I take of the play field takes too long (mostly 16’ish ms, but sometimes 30’ish ms), which limits its usability on high-BPM songs.
Are there any faster ways to take screenshots or some other methods that might suit my needs? Preferably I’d want to hit at least 8’ish ms on the 50x150px area, although if I can get even quicker that’d enable me to do checks that I can’t do right now due to time contraints in the screenshotting part.
Right now I’m using Graphics.CopyFromScreen, limiting its capture area to a small section (roughly 50x150px). From googling, I also found a method using BitBlt which seems to be way faster (taking essentially zero time), but it doesn’t seem to work as it should (and I don’t think it’s related to my code; when I take a screenshot using that method, the first time I get the current screen, but all subsequent screenshots made returns the first screen again, even if I restart my own program; it only serves a new screenshot after I restart the game).
Most of the code regarding the screenshots have been lifted straight from other examples, but I’ve made a couple of modifications myself to make them suit my needs better.
public static Bitmap CaptureImage(IntPtr handle, Rectangle? coords)
{
Rectangle bounds;
Rect rect = new Rect();
GetWindowRect(handle, ref rect);
if (coords == null)
bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
else
bounds = new Rectangle(rect.Left+coords.Value.X, rect.Top+coords.Value.Y, coords.Value.Width, coords.Value.Height);
Bitmap result = new Bitmap(bounds.Width, bounds.Height);
using (Graphics g = Graphics.FromImage(result))
{
Stopwatch sw = new Stopwatch();
sw.Start();
g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size, CopyPixelOperation.SourceCopy);
sw.Stop();
Console.WriteLine("Time to take screenshot: " + sw.ElapsedMilliseconds);
}
return result;
}
public Bitmap getBitmapAt(Point location, int width, int height)
{
Bitmap sImg = new Bitmap(width, height, PixelFormat.Format32bppArgb);
using (Graphics gsrc = Graphics.FromHwnd(windowHandle))
{
using (Graphics gdest = Graphics.FromImage(sImg))
{
IntPtr hSrcDC = gsrc.GetHdc();
IntPtr hDC = gdest.GetHdc();
int retval = BitBlt(hDC, 0, 0, width, height, hSrcDC, location.X, location.Y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
gsrc.Dispose();
}
return sImg;
}
Toll is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.