patterncsharpMinor
Capturing and taking a screenshot of a window in a loop
Viewed 0 times
capturingloopscreenshotandwindowtaking
Problem
I am capturing a window of my own choice, and taking a screenshot of it constantly in a loop. Latency and speed is everything.
It's very capable, but I hope it can be improved.
I will set a name
I then return the memory stream , and then I can do what I want with it (lz4 is used here to compress, which is very fast and lossless so it works pretty well).
Here are the
Then there is the
Now, is there a way to improve the speed? Preferably I would like to improve the latency, meaning the frame it lags behind.
I am willing to try something else if user32 is not enough for this, so I'm open for suggestions and examples on that.
Can this code be improved?
```
NetSerializer.Serializer.Serialize(tcpcap.GetStream(), PrintWindow(process));
PrintWindow(process).Dispose();
panel1.BackgroundImage = Image.FromStream(new Lz4DecompressionStream
It's very capable, but I hope it can be improved.
var proc = Process.GetProcessesByName(prcname)[0];
IntPtr hwnd = proc.MainWindowHandle;
RECT rc;
NativeMethods.GetWindowRect(hwnd, out rc);
Bitmap bmp = new Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics gfxBmp = Graphics.FromImage(bmp);
IntPtr hdcBitmap = gfxBmp.GetHdc();
NativeMethods.PrintWindow(hwnd, hdcBitmap, 0);
gfxBmp.ReleaseHdc(hdcBitmap);
gfxBmp.Dispose();
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
return new MemoryStream(Lz4.CompressBytes(ms.GetBuffer()));I will set a name
prcname which will be the name of a process, for example, Internet Explorer. It will then hook on to that and save it as a bitmap and then .bmp (or other).I then return the memory stream , and then I can do what I want with it (lz4 is used here to compress, which is very fast and lossless so it works pretty well).
Here are the
Imports used:[DllImport("user32.dll")]
internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
internal static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);Then there is the
RECT class, which is enormous, and I did not write it. I took it and reused this code for my own purposes, but RECT has been untouched, as I don't feel safe messing around with it.Now, is there a way to improve the speed? Preferably I would like to improve the latency, meaning the frame it lags behind.
I am willing to try something else if user32 is not enough for this, so I'm open for suggestions and examples on that.
Can this code be improved?
```
NetSerializer.Serializer.Serialize(tcpcap.GetStream(), PrintWindow(process));
PrintWindow(process).Dispose();
panel1.BackgroundImage = Image.FromStream(new Lz4DecompressionStream
Solution
Well, yes, you're holding on to a bunch of
Plus, the
IDisposable objects which should be dealt with by employing the using statement:IntPtr hwnd;
using (var proc = Process.GetProcessesByName(prcname)[0])
{
hwnd = proc.MainWindowHandle;
}
RECT rc;
NativeMethods.GetWindowRect(hwnd, out rc);
using (Bitmap bmp = new Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb))
{
using (Graphics gfxBmp = Graphics.FromImage(bmp))
{
IntPtr hdcBitmap = gfxBmp.GetHdc();
try
{
NativeMethods.PrintWindow(hwnd, hdcBitmap, 0);
}
finally
{
gfxBmp.ReleaseHdc(hdcBitmap);
}
}
using (MemoryStream ms = new MemoryStream())
{
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
return new MemoryStream(Lz4.CompressBytes(ms.GetBuffer()));
}
}Plus, the
MemoryStream you return should be Dispose()'d be the calling code.Code Snippets
IntPtr hwnd;
using (var proc = Process.GetProcessesByName(prcname)[0])
{
hwnd = proc.MainWindowHandle;
}
RECT rc;
NativeMethods.GetWindowRect(hwnd, out rc);
using (Bitmap bmp = new Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb))
{
using (Graphics gfxBmp = Graphics.FromImage(bmp))
{
IntPtr hdcBitmap = gfxBmp.GetHdc();
try
{
NativeMethods.PrintWindow(hwnd, hdcBitmap, 0);
}
finally
{
gfxBmp.ReleaseHdc(hdcBitmap);
}
}
using (MemoryStream ms = new MemoryStream())
{
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
return new MemoryStream(Lz4.CompressBytes(ms.GetBuffer()));
}
}Context
StackExchange Code Review Q#29364, answer score: 5
Revisions (0)
No revisions yet.