Goal: Using P/Invoke to capture specified portion of screen to byte[]
Hello, this is my first Code Review post and also first project.
After a week of searching and testing each approach via Stopwatch,
I came to this method using the fastest way possible to capture screen into a bitmap and then to a byte[].
Is it possible to make it any faster using parallel features or any idea I have not taken into account? (As I am a newbie, 4 months of self learning.)
I mixed two or three versions of the copying function (portion of screen to memory then convert captured/crop into
byte[]). I might have left unnecessary lines of code, I would like to refine it (if and where needed).
If something is not clear, please let me know.
Thanks a lot, here is the code:
unsafe public static Bitmap NatUnsfBtmp(IntPtr hWnd, Size Ms)
{
Stopwatch swCap2Byte = new Stopwatch();
swCap2Byte.Start();
WINDOWINFO winInfo = new WINDOWINFO();
bool ret = GetWindowInfo(hWnd, ref winInfo);
if (!ret)
{
return null;
}
int height = Ms.Height;
int width = Ms.Width;
if (height == 0 || width == 0) return null;
Graphics frmGraphics = Graphics.FromHwnd(hWnd);
IntPtr hDC = GetWindowDC(hWnd); //gets the entire window
//IntPtr hDC = frmGraphics.GetHdc(); -- gets the client area, no menu bars, etc..
System.Drawing.Bitmap tmpBitmap = new System.Drawing.Bitmap(width, height, frmGraphics);
Bitmap bitmap = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
Graphics bmGraphics = Graphics.FromImage(tmpBitmap);
IntPtr bmHdc = bmGraphics.GetHdc();
BitBlt(bmHdc, 0, 0, width, height, hDC, 0, 0, TernaryRasterOperations.SRCCOPY);
swCap2Byte.Stop();
string swCopiedFF = swCap2Byte.Elapsed.ToString().Remove(0, 5);
swCap2Byte.Restart();
#region <<=========== CopytoMem->ByteArr ============>>
BitmapData bData = tmpBitmap.LockBits(new Rectangle(new Point(), Ms),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
MyForm1.MyT.Cap.TestBigCapturedBtmp = tmpBitmap;
// number of bytes in the bitmap
int byteCount = bData.Stride * tmpBitmap.Height;
byte[] bmpBytes = new byte[byteCount];
// Copy the locked bytes from memory
Marshal.Copy(bData.Scan0, bmpBytes, 0, byteCount);
byte[] OrgArr = bmpBytes;//File.ReadAllBytes("testFcompScr.bmp");
// don't forget to unlock the bitmap!!
swCap2Byte.Stop();
string SwFCFscr = swCap2Byte.Elapsed.ToString().Remove(0, 5);
System.IO.File.WriteAllBytes(MyForm1.AHItemsInitialDir + "testBig4BenchViaChaos.bar", OrgArr);
System.Windows.Forms.MessageBox.Show(" Copied @ " +swCopiedFF + Environment.NewLine+"Converted @ " + SwFCFscr);
btmp.UnlockBits(bData);
if(System.IO.File.ReadAllBytes(MyForm1.AHItemsInitialDir + "testBig4BenchViaChaos.bar")== OrgArr)
System.Windows.Forms.MessageBox.Show("OK");
else System.Windows.Forms.MessageBox.Show("Not same");
if (BigOrsmall == "Big")
{
MyT.Cap.TestBigCapturedBtmp = btmp;
MyT.CapSave.TestBigCaptSavedAsBar = OrgArr;
File.WriteAllBytes(AHItemsInitialDir + "testBig4BenchViaChaos.bar", OrgArr);
}
else if (BigOrsmall == "Small")
{
MyT.Cap.TestSmallCapturedBtmp = btmp;
File.WriteAllBytes(AHItemsInitialDir + "testSmall4BenchViaChaos.bar", OrgArr);
MyT.CapSave.TestSmallCaptSavedAsBar = OrgArr;
}
TestedCap_DoPutInPicBox(PicBox_CopiedFromScreen);
#endregion
bmGraphics.ReleaseHdc(bmHdc);
ReleaseDC(hWnd, hDC);
return tmpBitmap;
}
GetWindowInfo()to the bitmap converted from pixels on screen. i gonna resarch on this let me know if you have a clue Y. – Robbie banay Sep 5 '12 at 22:51