Dear C# professionals.
Is this possible to optimize the code of screenshot capture and make it directly to byte array without intermediate bmp? The code I use now contains of two functions. First function CreateBitmapFromWindow accepts a pointer to the window and returns bitmap, corresponding to window rectangle. Second function translates bitmap to byte array via Marshal.Copy. I dont write unmanaged methods class here. Methods are standard and taken from msdn:
Code:public Bitmap CreateBitmapFromWindow(IntPtr hwnd) { Rect rec; IntPtr hDC; Bitmap bmp; //calculating window dimensions UnmanagedMethods.GetWindowRect(hwnd, out rec); //Here we get the handle to the window device context. hDC = UnmanagedMethods.GetDCEx(hwnd, UnmanagedMethods.CreateRectRgn(rec.Left, rec.Top, rec.Right, rec.Bottom),UnmanagedMethods.DCX_WINDOW); //Here we make a compatible device context in memory for window or screen device context. IntPtr hMemDC = UnmanagedMethods.CreateCompatibleDC(hDC); //We create a compatible bitmap of the screen size and using the screen device context. IntPtr hBitmap = UnmanagedMethods.CreateCompatibleBitmap(hDC, rec.Right - rec.Left, rec.Bottom - rec.Top); //Here we select the compatible bitmap in the memeory device //context and keep the refrence to the old bitmap. IntPtr hOld = UnmanagedMethods.SelectObject(hMemDC, hBitmap); //We copy the Bitmap to the memory device context. UnmanagedMethods.BitBlt(hMemDC, 0, 0, rec.Right - rec.Left, rec.Bottom - rec.Top, hDC, 0, 0, UnmanagedMethods.SRCCOPY); //We select the old bitmap back to the memory device context. UnmanagedMethods.SelectObject(hMemDC, hOld); //We delete the memory device context. UnmanagedMethods.DeleteDC(hMemDC); //We release the screen device context. UnmanagedMethods.ReleaseDC(hwnd, hDC); //Image is created by Image bitmap handle and stored in local variable. bmp = Image.FromHbitmap(hBitmap); //Release the memory to avoid memory leaks. UnmanagedMethods.DeleteObject(hBitmap); //This statement runs the garbage collector manually. GC.Collect(); return bmp; } //Second function translates bmp to byte array public byte[] BMPToByteArray(Bitmap bmp) { Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); //I use only 24b BMPs BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); IntPtr ptr = bmpData.Scan0; int bytes = bmpData.Stride * bmp.Height; byte[] rgbValues = new byte[bytes]; Marshal.Copy(ptr, rgbValues, 0, bytes); bmp.UnlockBits(bmpData); return rgbValues; } [StructLayout(LayoutKind.Sequential)] public struct Rect { public int Left; public int Top; public int Right; public int Bottom; }


Reply With Quote

Bookmarks