public Image CaptureWindow(IntPtr handle) { // get te hDC of the target window IntPtr hdcSrc = User32.GetWindowDC(handle); // get the size User32.RECT windowRect = new User32.RECT(); User32.GetWindowRect(handle, ref windowRect); int width = windowRect.right - windowRect.left; int height = windowRect.bottom - windowRect.top; // create a device context we can copy to IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc); // create a bitmap we can copy it to, // using GetDeviceCaps to get the width/height IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height); // select the bitmap object IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap); // bitblt over GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY); // restore selection GDI32.SelectObject(hdcDest, hOld); // clean up GDI32.DeleteDC(hdcDest); User32.ReleaseDC(handle, hdcSrc); // get a .NET image object for it Image img = Image.FromHbitmap(hBitmap); // free up the Bitmap object GDI32.DeleteObject(hBitmap); return(img); }
public override int Capture(FrameInfo frame) { try { //var success = Native.BitBlt(CompatibleDeviceContext, 0, 0, Width, Height, WindowDeviceContext, Left, Top, Native.CopyPixelOperation.SourceCopy | Native.CopyPixelOperation.CaptureBlt); var success = Gdi32.StretchBlt(CompatibleDeviceContext, 0, 0, StartWidth, StartHeight, WindowDeviceContext, Left, Top, Width, Height, PixelOperations); if (!success) { return(FrameCount); } //Set frame details. FrameCount++; frame.Path = $"{Project.FullPath}{FrameCount}.png"; frame.Delay = FrameRate.GetMilliseconds(); frame.Image = Image.FromHbitmap(CompatibleBitmap); if (IsAcceptingFrames) { BlockingCollection.Add(frame); } } catch (Exception) { //LogWriter.Log(ex, "Impossible to get the screenshot of the screen"); } return(FrameCount); }
/// <summary> /// 截图 /// </summary> private void CaptureImage(string filePath) { if (File.Exists(filePath)) { File.Delete(filePath); } var rect = Screen.PrimaryScreen.Bounds; var size = new Size(pbImg.Width, pbImg.Height); using (var bitmap = new Bitmap(rect.Width, rect.Height)) { var grp = Graphics.FromImage(bitmap); var location = new Point(Left + 8, Top + 32); grp.CopyFromScreen(location, new Point(0, 0), size); grp.ReleaseHdc(grp.GetHdc()); bitmap.Save(filePath); } using (var srcImg = Image.FromFile(filePath)) using (var bitmap = new Bitmap(pbImg.Width, pbImg.Height)) using (var grp = Graphics.FromImage(bitmap)) { grp.DrawImage(srcImg, 0, 0, new Rectangle(new Point(), size), GraphicsUnit.Pixel); srcImg.Dispose(); using (Image newImg = Image.FromHbitmap(bitmap.GetHbitmap())) newImg.Save(filePath, ImageFormat.Jpeg); } }
private void inkCanvas_MouseDown(object sender, MouseButtonEventArgs e) { if (mainView.IsEllipse || mainView.IsLine || mainView.IsRectangle || mainView.IsText || mainView.IsPie || mainView.IsArc) { drawing = true; } Image img = Image.FromHbitmap(mainView.WorkImage.GetHbitmap()); tempBitmap = new Bitmap(img); startPoint = e.GetPosition(inkCanvas); }
public override int CaptureWithCursor(FrameInfo frame) { try { //var success = Native.BitBlt(CompatibleDeviceContext, 0, 0, Width, Height, WindowDeviceContext, Left, Top, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); var success = Gdi32.StretchBlt(CompatibleDeviceContext, 0, 0, StartWidth, StartHeight, WindowDeviceContext, Left, Top, Width, Height, PixelOperations); if (!success) { return(FrameCount); } #region Cursor try { var cursorInfo = new CursorInfo(); cursorInfo.cbSize = Marshal.SizeOf(cursorInfo); if (User32.GetCursorInfo(out cursorInfo)) { if (cursorInfo.flags == Native.Constants.CursorShowing) { var hicon = User32.CopyIcon(cursorInfo.hCursor); if (hicon != IntPtr.Zero) { if (User32.GetIconInfo(hicon, out var iconInfo)) { frame.CursorX = cursorInfo.ptScreenPos.X - Left; frame.CursorY = cursorInfo.ptScreenPos.Y - Top; //(int)(SystemParameters.CursorHeight * Scale) //(int)(SystemParameters.CursorHeight * Scale) var ok = User32.DrawIconEx(CompatibleDeviceContext, frame.CursorX - iconInfo.xHotspot, frame.CursorY - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, CursorStep, IntPtr.Zero, 0x0003); if (!ok) { CursorStep = 0; User32.DrawIconEx(CompatibleDeviceContext, frame.CursorX - iconInfo.xHotspot, frame.CursorY - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, CursorStep, IntPtr.Zero, 0x0003); } else { CursorStep++; } } Gdi32.DeleteObject(iconInfo.hbmColor); Gdi32.DeleteObject(iconInfo.hbmMask); } User32.DestroyIcon(hicon); } Gdi32.DeleteObject(cursorInfo.hCursor); } } catch (Exception) { //LogWriter.Log(e, "Impossible to get the cursor"); } #endregion //Set frame details. FrameCount++; frame.Path = $"{Project.FullPath}{FrameCount}.png"; frame.Delay = FrameRate.GetMilliseconds(); frame.Image = Image.FromHbitmap(CompatibleBitmap); if (IsAcceptingFrames) { BlockingCollection.Add(frame); } } catch (Exception) { //LogWriter.Log(ex, "Impossible to get the screenshot of the screen"); } return(FrameCount); }
private static void SaveImageAs(int hBitmap, Stream str, ImageFormat imageFormat) { Image.FromHbitmap(new IntPtr(hBitmap)).Save(str, imageFormat); }
private unsafe Bitmap BmpFrame() { Bitmap?bitmap = null; if (_iconData != null && _bestBitDepth == 32) { // GDI+ doesnt handle 32 bpp icons with alpha properly // we load the icon ourself from the byte table bitmap = new Bitmap(Size.Width, Size.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Debug.Assert(_bestImageOffset >= 0 && (_bestImageOffset + _bestBytesInRes) <= _iconData.Length, "Illegal offset/length for the Icon data"); unsafe { BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, Size.Width, Size.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); try { uint *pixelPtr = (uint *)bmpdata.Scan0.ToPointer(); // jumping the image header int newOffset = (int)(_bestImageOffset + Marshal.SizeOf(typeof(SafeNativeMethods.BITMAPINFOHEADER))); // there is no color table that we need to skip since we're 32bpp int lineLength = Size.Width * 4; int width = Size.Width; for (int j = (Size.Height - 1) * 4; j >= 0; j -= 4) { Marshal.Copy(_iconData, newOffset + j * width, (IntPtr)pixelPtr, lineLength); pixelPtr += width; } // note: we ignore the mask that's available after the pixel table } finally { bitmap.UnlockBits(bmpdata); } } } else if (_bestBitDepth == 0 || _bestBitDepth == 32) { // This may be a 32bpp icon or an icon without any data. SafeNativeMethods.ICONINFO info = default; SafeNativeMethods.GetIconInfo(new HandleRef(this, _handle), ref info); SafeNativeMethods.BITMAP bmp = default; try { if (info.hbmColor != IntPtr.Zero) { SafeNativeMethods.GetObject(new HandleRef(null, info.hbmColor), sizeof(SafeNativeMethods.BITMAP), ref bmp); if (bmp.bmBitsPixel == 32) { Bitmap? tmpBitmap = null; BitmapData?bmpData = null; BitmapData?targetData = null; try { tmpBitmap = Image.FromHbitmap(info.hbmColor); // In GDI+ the bits are there but the bitmap was created with no alpha channel // so copy the bits by hand to a new bitmap // we also need to go around a limitation in the way the ICON is stored (ie if it's another bpp // but stored in 32bpp all pixels are transparent and not opaque) // (Here you mostly need to remain calm....) bmpData = tmpBitmap.LockBits(new Rectangle(0, 0, tmpBitmap.Width, tmpBitmap.Height), ImageLockMode.ReadOnly, tmpBitmap.PixelFormat); // we need do the following if the image has alpha because otherwise the image is fully transparent even though it has data if (BitmapHasAlpha(bmpData)) { bitmap = new Bitmap(bmpData.Width, bmpData.Height, PixelFormat.Format32bppArgb); targetData = bitmap.LockBits(new Rectangle(0, 0, bmpData.Width, bmpData.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); CopyBitmapData(bmpData, targetData); } } finally { if (tmpBitmap != null && bmpData != null) { tmpBitmap.UnlockBits(bmpData); } if (bitmap != null && targetData != null) { bitmap.UnlockBits(targetData); } } tmpBitmap.Dispose(); } } } finally { if (info.hbmColor != IntPtr.Zero) { Interop.Gdi32.DeleteObject(info.hbmColor); } if (info.hbmMask != IntPtr.Zero) { Interop.Gdi32.DeleteObject(info.hbmMask); } } } if (bitmap == null) { // last chance... all the other cases (ie non 32 bpp icons coming from a handle or from the bitmapData) // we have to do this rather than just return Bitmap.FromHIcon because // the bitmap returned from that, even though it's 32bpp, just paints where the mask allows it // seems like another GDI+ weirdness. might be interesting to investigate further. In the meantime // this looks like the right thing to do and is not more expansive that what was present before. Size size = Size; bitmap = new Bitmap(size.Width, size.Height); // initialized to transparent Graphics?graphics = null; using (graphics = Graphics.FromImage(bitmap)) { try { using (Bitmap tmpBitmap = Bitmap.FromHicon(Handle)) { graphics.DrawImage(tmpBitmap, new Rectangle(0, 0, size.Width, size.Height)); } } catch (ArgumentException) { // Sometimes FromHicon will crash with no real reason. // The backup plan is to just draw the image like we used to. // NOTE: FromHIcon is also where we have the buffer overrun // if width and height are mismatched. Draw(graphics, new Rectangle(0, 0, size.Width, size.Height)); } } // GDI+ fills the surface with a sentinel color for GetDC, but does // not correctly clean it up again, so we have to do it. Color fakeTransparencyColor = Color.FromArgb(0x0d, 0x0b, 0x0c); bitmap.MakeTransparent(fakeTransparencyColor); } Debug.Assert(bitmap != null, "Bitmap cannot be null"); return(bitmap); }
private void inkCanvas_MouseMove(object sender, MouseEventArgs e) { if (drawing) { Pen pen = new Pen(System.Drawing.Color.FromArgb(255, mainView.ResultColor.R, mainView.ResultColor.G, mainView.ResultColor.B )); pen.Width = Convert.ToSingle(mainView.BorderWidth); if (!mainView.IsExperiment) { Image img = Image.FromHbitmap(tempBitmap.GetHbitmap()); mainView.WorkImage = new Bitmap(img); } Graphics g = Graphics.FromImage(mainView.WorkImage); SolidBrush brush = new SolidBrush(pen.Color); Point point = e.GetPosition(inkCanvas); if (mainView.IsRectangle) { RectangleF rect = new RectangleF(Math.Min((int)startPoint.X, (int)point.X), Math.Min((int)startPoint.Y, (int)point.Y), Math.Abs((int)point.X - (int)startPoint.X), Math.Abs((int)point.Y - (int)startPoint.Y)); if (mainView.IsFill) { g.FillRectangle(brush, rect); } else { g.DrawRectangle(pen, System.Drawing.Rectangle.Round(rect)); } } else if (mainView.IsEllipse) { RectangleF rect = new RectangleF((int)startPoint.X, (int)startPoint.Y, (int)point.X - (int)startPoint.X, (int)point.Y - (int)startPoint.Y); if (mainView.IsFill) { g.FillEllipse(brush, rect); } else { g.DrawEllipse(pen, System.Drawing.Rectangle.Round(rect)); } } else if (mainView.IsLine) { g.DrawLine(pen, (int)startPoint.X, (int)startPoint.Y, (int)point.X, (int)point.Y); } else if (mainView.IsText) { g.DrawString(mainView.ResultText, mainView.ResultFont, brush, (int)point.X, (int)point.Y); } else if (mainView.IsArc) { RectangleF rect = new RectangleF(Math.Min((int)startPoint.X, (int)point.X), Math.Min((int)startPoint.Y, (int)point.Y), Math.Abs((int)point.X - (int)startPoint.X), Math.Abs((int)point.Y - (int)startPoint.Y)); try { g.DrawArc(pen, rect, mainView.StartAngle, mainView.SweepAngle); } catch { }; } if (mainView.IsPie) { System.Drawing.Rectangle rect = new System.Drawing.Rectangle(Math.Min((int)startPoint.X, (int)point.X), Math.Min((int)startPoint.Y, (int)point.Y), Math.Abs((int)point.X - (int)startPoint.X), Math.Abs((int)point.Y - (int)startPoint.Y)); try { if (mainView.IsFill) { g.FillPie(brush, rect, mainView.StartAngle, mainView.SweepAngle); } else { g.DrawPie(pen, rect, mainView.StartAngle, mainView.SweepAngle); } } catch { }; } mainView.WorkImage = mainView.WorkImage; } }