patterncsharpMinor
Reading a certain pixels color from a window
Viewed 0 times
fromreadingcolorpixelswindowcertain
Problem
I'm currently reading a certain pixels color from a process window like this:
It seems to be working.
I would like to know if I'm disposing everything that I use correctly to avoid memory leaks. If I inspect my app in the task manager I notice that the memory use is increasing a bit for each time i fetch a pixel, but I suppose the garbage collector will kick in when it's supposed to?
Also, is there any obvious "better" way of doing this?
[DllImport("gdi32.dll")]
private static extern int BitBlt(IntPtr srchDc, int srcX, int srcY, int srcW, int srcH,
IntPtr desthDc, int destX, int destY, int op);
public static Color GetPixel(IntPtr hwnd, int x, int y)
{
var screenPixel = new Bitmap(1, 1);
using (Graphics gdest = Graphics.FromImage(screenPixel))
{
using (Graphics gsrc = Graphics.FromHwnd(MemoryHandler.GetMainWindowHandle()))
{
IntPtr hsrcdc = gsrc.GetHdc();
IntPtr hdc = gdest.GetHdc();
BitBlt(hdc, 0, 0, 1, 1, hsrcdc, x, y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
}
return screenPixel.GetPixel(0, 0);
}It seems to be working.
I would like to know if I'm disposing everything that I use correctly to avoid memory leaks. If I inspect my app in the task manager I notice that the memory use is increasing a bit for each time i fetch a pixel, but I suppose the garbage collector will kick in when it's supposed to?
Also, is there any obvious "better" way of doing this?
Solution
You'll actually need to wrap the
Further, the garbage collector works almost immediately. Or more simply put, if you use a memory allocation tool like MemProfiler, the memory will get cleaned up by GC faster than you can collect it with a snapshot. The
It may also be worth wrapping the API call in a
to ensure the
Bitmap in a using as well because its base class, Image, implements IDisposable:public static Color GetPixel(IntPtr hwnd, int x, int y)
{
using (Bitmap screenPixel = new Bitmap(1, 1);
{
using (Graphics gdest = Graphics.FromImage(screenPixel))
{
using (Graphics gsrc = Graphics.FromHwnd(MemoryHandler.GetMainWindowHandle()))
{
IntPtr hsrcdc = gsrc.GetHdc();
IntPtr hdc = gdest.GetHdc();
BitBlt(hdc, 0, 0, 1, 1, hsrcdc, x, y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
}
return screenPixel.GetPixel(0, 0);
}
}Further, the garbage collector works almost immediately. Or more simply put, if you use a memory allocation tool like MemProfiler, the memory will get cleaned up by GC faster than you can collect it with a snapshot. The
Bitmap is likely where you are seeing the little tick.It may also be worth wrapping the API call in a
try ... finally:IntPtr hsrcdc = gsrc.GetHdc();
IntPtr hdc = gdest.GetHdc();
try
{
using (Graphics gsrc = Graphics.FromHwnd(MemoryHandler.GetMainWindowHandle()))
{
BitBlt(hdc, 0, 0, 1, 1, hsrcdc, x, y, (int)CopyPixelOperation.SourceCopy);
}
}
finally
{
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}to ensure the
ReleaseHdc gets called.Code Snippets
public static Color GetPixel(IntPtr hwnd, int x, int y)
{
using (Bitmap screenPixel = new Bitmap(1, 1);
{
using (Graphics gdest = Graphics.FromImage(screenPixel))
{
using (Graphics gsrc = Graphics.FromHwnd(MemoryHandler.GetMainWindowHandle()))
{
IntPtr hsrcdc = gsrc.GetHdc();
IntPtr hdc = gdest.GetHdc();
BitBlt(hdc, 0, 0, 1, 1, hsrcdc, x, y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
}
return screenPixel.GetPixel(0, 0);
}
}IntPtr hsrcdc = gsrc.GetHdc();
IntPtr hdc = gdest.GetHdc();
try
{
using (Graphics gsrc = Graphics.FromHwnd(MemoryHandler.GetMainWindowHandle()))
{
BitBlt(hdc, 0, 0, 1, 1, hsrcdc, x, y, (int)CopyPixelOperation.SourceCopy);
}
}
finally
{
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}Context
StackExchange Code Review Q#36899, answer score: 5
Revisions (0)
No revisions yet.