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;
}