public static void DoubleBufferPaint(IntPtr hDC, int x, int y, int width, int height, PaintCoreProc paintCore) { IntPtr hDC2 = Gdi32.CreateCompatibleDC(hDC); IntPtr hBmp = Gdi32.CreateCompatibleBitmap(hDC, width, height); Gdi32.SelectObject(hDC2, hBmp); Gdi32.DeleteObject(hBmp); Graphics g = Graphics.FromHdc(hDC2); paintCore(g); g.Dispose(); Gdi32.BitBlt(hDC, x, y, width, height, hDC2, 0, 0, Gdi32.SRCCOPY); Gdi32.DeleteDC(hDC2); }
private static Bitmap CaptureDesktopToBitmap(int width, int height, Action <IntPtr, IntPtr> action) { // Use P/Invoke because of: https://stackoverflow.com/a/3072580/1069200 var hDesk = User32.GetDesktopWindow(); var hSrc = User32.GetWindowDC(hDesk); var hDest = Gdi32.CreateCompatibleDC(hSrc); var hBmp = Gdi32.CreateCompatibleBitmap(hSrc, width, height); var hPrevBmp = Gdi32.SelectObject(hDest, hBmp); action(hDest, hSrc); var bmp = Image.FromHbitmap(hBmp); Gdi32.SelectObject(hDest, hPrevBmp); Gdi32.DeleteObject(hBmp); Gdi32.DeleteDC(hDest); User32.ReleaseDC(hDesk, hSrc); return(bmp); }
public static Bitmap TakeSnapshot(IViewObject obj, int width, int height) { // draw the view on a Bitmap IntPtr hBitmapDC = IntPtr.Zero; IntPtr hBitmap = IntPtr.Zero; IntPtr hPreviousObject = IntPtr.Zero; Bitmap bitmap = null; try { // create GDI objects used for drawing hBitmapDC = Gdi32.CreateCompatibleDC(User32.GetDC(IntPtr.Zero)); hBitmap = Gdi32.CreateCompatibleBitmap(User32.GetDC(IntPtr.Zero), width, height); hPreviousObject = Gdi32.SelectObject(hBitmapDC, hBitmap); RECT sourceRect = new RECT(); sourceRect.right = width; sourceRect.bottom = height; // draw the bitmap obj.Draw(DVASPECT.CONTENT, 1, IntPtr.Zero, IntPtr.Zero, User32.GetDC(IntPtr.Zero), hBitmapDC, ref sourceRect, IntPtr.Zero, IntPtr.Zero, 0); // convert to a managed bitmap bitmap = Bitmap.FromHbitmap(hBitmap); } finally { // restore previous object Gdi32.SelectObject(hBitmapDC, hPreviousObject); if (hBitmapDC != IntPtr.Zero) { Gdi32.DeleteDC(hBitmapDC); } if (hBitmap != IntPtr.Zero) { Gdi32.DeleteObject(hBitmap); } } return(bitmap); }
/// <summary> /// Creates a new instance of <see cref="WindowProvider"/>. /// </summary> public WindowProvider(IWindow Window, bool IncludeCursor, out Func <Point, Point> Transform) { _window = Window ?? throw new ArgumentNullException(nameof(Window)); _includeCursor = IncludeCursor; var size = Window.Rectangle.Even().Size; Width = size.Width; Height = size.Height; Transform = _transform = GetTransformer(Window); _hdcSrc = User32.GetDC(IntPtr.Zero); _hdcDest = Gdi32.CreateCompatibleDC(_hdcSrc); _hBitmap = Gdi32.CreateCompatibleBitmap(_hdcSrc, Width, Height); Gdi32.SelectObject(_hdcDest, _hBitmap); }
public static Bitmap CaptureDesktop() { IntPtr hDC = User32.GetWindowDC(IntPtr.Zero), hMemDC = Gdi32.CreateCompatibleDC(hDC), hBitmap = Gdi32.CreateCompatibleBitmap(hDC, SystemParams.ScreenWidth, SystemParams.ScreenHeight); if (hBitmap == IntPtr.Zero) { return(null); } var hOld = Gdi32.SelectObject(hMemDC, hBitmap); Gdi32.BitBlt(hMemDC, 0, 0, SystemParams.ScreenWidth, SystemParams.ScreenHeight, hDC, 0, 0, CopyPixelOperation.SourceCopy); Gdi32.SelectObject(hMemDC, hOld); return(Bitmap.FromHbitmap(hBitmap)); }
/// <summary> /// Captures a specific area from the screen. /// </summary> public static CaptureImage Rectangle(Rectangle bounds) { // Use P/Invoke because of: https://stackoverflow.com/a/3072580/1069200 var sz = new System.Drawing.Size(bounds.Width, bounds.Height); var hDesk = User32.GetDesktopWindow(); var hSrce = User32.GetWindowDC(hDesk); var hDest = Gdi32.CreateCompatibleDC(hSrce); var hBmp = Gdi32.CreateCompatibleBitmap(hSrce, sz.Width, sz.Height); var hOldBmp = Gdi32.SelectObject(hDest, hBmp); Gdi32.BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSrce, bounds.X, bounds.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); var bmp = Image.FromHbitmap(hBmp); Gdi32.SelectObject(hDest, hOldBmp); Gdi32.DeleteObject(hBmp); Gdi32.DeleteDC(hDest); User32.ReleaseDC(hDesk, hSrce); return(new CaptureImage(bmp, bounds)); }
private void Render() { RECT rect = new RECT(); User32.GetWindowRect(_handle, ref rect); int width = rect.right - rect.left; int height = rect.bottom - rect.top; if (width == 0 || height == 0) { return; } IntPtr screenDc = User32.GetDC(IntPtr.Zero); IntPtr memDc = Gdi32.CreateCompatibleDC(screenDc); POINT newLocation = new POINT(rect.left, rect.top); SIZE newSize = new SIZE(width, height); using (Bitmap bmp = GetBitmap(width, height)) { IntPtr hBitmap = bmp.GetHbitmap(_transparent); IntPtr hOldBitmap = Gdi32.SelectObject(memDc, hBitmap); User32.UpdateLayeredWindow(_handle, screenDc, ref newLocation, ref newSize, memDc, ref _ptZero, 0, ref _blend, 0x02); User32.ReleaseDC(IntPtr.Zero, screenDc); if (hBitmap != IntPtr.Zero) { Gdi32.SelectObject(memDc, hOldBitmap); Gdi32.DeleteObject(hBitmap); } } Gdi32.DeleteDC(memDc); GC.Collect(); }
//This class is used to take screen shots of the desktop and convert them to the BitmapSource //This method takes screen shot of the specified region of the desktop public BitmapSource CaptureRegion(IntPtr hWnd, int x, int y, int width, int height, bool addToClipboard) { IntPtr sourceDC = IntPtr.Zero; IntPtr targetDC = IntPtr.Zero; IntPtr compatibleBitmapHandle = IntPtr.Zero; BitmapSource bitmap = null; try { // gets the main desktop and all open windows sourceDC = User32.GetDC(User32.GetDesktopWindow()); targetDC = Gdi32.CreateCompatibleDC(sourceDC); // create a bitmap compatible with our target DC compatibleBitmapHandle = Gdi32.CreateCompatibleBitmap(sourceDC, width, height); // gets the bitmap into the target device context Gdi32.SelectObject(targetDC, compatibleBitmapHandle); // copy from source to destination Gdi32.BitBlt(targetDC, 0, 0, width, height, sourceDC, x, y, Gdi32.SRCCOPY); // Here's the WPF glue to make it all work. It converts from an // hBitmap to a BitmapSource. Love the WPF interop functions bitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( compatibleBitmapHandle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); } catch (Exception ex) { throw new Exception(string.Format("Error capturing region {0},{1},{2},{3}", x, y, width, height), ex); } finally { Gdi32.DeleteObject(compatibleBitmapHandle); User32.ReleaseDC(IntPtr.Zero, sourceDC); User32.ReleaseDC(IntPtr.Zero, targetDC); } return(bitmap); }
internal MetafileDCWrapper(IntPtr hOriginalDC, Size size) { Debug.Assert(Gdi32.GetObjectType(hOriginalDC) == Gdi32.ObjectType.OBJ_ENHMETADC, "Why wrap a non-Enhanced MetaFile DC?"); if (size.Width < 0 || size.Height < 0) { throw new ArgumentException(SR.ControlMetaFileDCWrapperSizeInvalid, nameof(size)); } _hMetafileDC = hOriginalDC; _destRect = new RECT(0, 0, size.Width, size.Height); HDC = Gdi32.CreateCompatibleDC(IntPtr.Zero); int planes = Gdi32.GetDeviceCaps(HDC, Gdi32.DeviceCapability.PLANES); int bitsPixel = Gdi32.GetDeviceCaps(HDC, Gdi32.DeviceCapability.BITSPIXEL); _hBitmap = SafeNativeMethods.CreateBitmap(size.Width, size.Height, planes, bitsPixel, IntPtr.Zero); _hOriginalBmp = Gdi32.SelectObject(HDC, _hBitmap); }
/// <summary> /// Gets Image object containing screen shot /// </summary> /// <param name="handle">The handle to the window. /// <returns></returns> public Image CaptureWindow(IntPtr handle) { var hdcSrc = User32.GetWindowDC(handle); var windowRect = new User32.Rect(); User32.GetWindowRect(handle, ref windowRect); var width = windowRect.right - windowRect.left; var height = windowRect.bottom - windowRect.top; var hdcDest = Gdi32.CreateCompatibleDC(hdcSrc); var hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height); var hOld = Gdi32.SelectObject(hdcDest, hBitmap); Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, Gdi32.Srccopy); Gdi32.SelectObject(hdcDest, hOld); Gdi32.DeleteDC(hdcDest); User32.ReleaseDC(handle, hdcSrc); Image img = Image.FromHbitmap(hBitmap); Gdi32.DeleteObject(hBitmap); return(img); }
virtual public Bitmap this[IntPtr hWnd, int x, int y, int width, int height] { get{ IntPtr wndHDC = GetDC(hWnd); IntPtr capHDC = Gdi32.CreateCompatibleDC(wndHDC); IntPtr capBMP = Gdi32.CreateCompatibleBitmap(wndHDC, width, height); if (capBMP == IntPtr.Zero) { ReleaseDC(hWnd, wndHDC); Gdi32.DeleteDC(capHDC); return(null); } IntPtr prvHDC = (IntPtr)Gdi32.SelectObject(capHDC, capBMP); Gdi32.BitBlt(capHDC, 0, 0, width, height, wndHDC, x, y, Gdi32.SRCCOPY); // managed: CompositeMode Gdi32.SelectObject(capHDC, prvHDC); Bitmap bmp = System.Drawing.Image.FromHbitmap(capBMP); ReleaseDC(hWnd, wndHDC); // release window context Gdi32.DeleteDC(capHDC); // delete capture context Gdi32.DeleteObject(capBMP); // delete capture bitmap return(bmp); // return bitmap } }
public static Image CaptureWindow(IntPtr handle) { IntPtr hdcSrc = User32.GetWindowDC(handle); RECT windowRect = new RECT(); User32.GetWindowRect(handle, ref windowRect); int width = windowRect.right - windowRect.left; int height = windowRect.bottom - windowRect.top; IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc); IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height); IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap); Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, ApiConstants.SRCCOPY); Gdi32.SelectObject(hdcDest, hOld); Gdi32.DeleteDC(hdcDest); User32.ReleaseDC(handle, hdcSrc); Image image = Image.FromHbitmap(hBitmap); Gdi32.DeleteObject(hBitmap); return(image); }
/// <summary> /// Windows only window capture by handle /// </summary> /// <param name="handle"></param> /// <returns></returns> private static byte[] CaptureWindowPng(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); byte[] ret = null; // get a .NET image object for it using (Bitmap img = Image.FromHbitmap(hBitmap)) { // free up the Bitmap object Gdi32.DeleteObject(hBitmap); // Saving to stream using (var m = new MemoryStream()) { img.Save(m, ImageFormat.Png); ret = m.ToArray(); } } return(ret); }
private IntPtr GetCompatibleBitmap(Bitmap bm) { using ScreenDC hDC = ScreenDC.Create(); // GDI+ returns a DIBSECTION based HBITMAP. The clipboard deals well // only with bitmaps created using CreateCompatibleBitmap(). So, we // convert the DIBSECTION into a compatible bitmap. IntPtr hBitmap = bm.GetHbitmap(); // Create a compatible DC to render the source bitmap. IntPtr dcSrc = Gdi32.CreateCompatibleDC(hDC); IntPtr srcOld = Gdi32.SelectObject(dcSrc, hBitmap); // Create a compatible DC and a new compatible bitmap. IntPtr dcDest = Gdi32.CreateCompatibleDC(hDC); IntPtr hBitmapNew = Gdi32.CreateCompatibleBitmap(hDC, bm.Size.Width, bm.Size.Height); // Select the new bitmap into a compatible DC and render the blt the original bitmap. IntPtr destOld = Gdi32.SelectObject(dcDest, hBitmapNew); Gdi32.BitBlt( dcDest, 0, 0, bm.Size.Width, bm.Size.Height, dcSrc, 0, 0, Gdi32.ROP.SRCCOPY); // Clear the source and destination compatible DCs. Gdi32.SelectObject(dcSrc, srcOld); Gdi32.SelectObject(dcDest, destOld); Gdi32.DeleteDC(dcSrc); Gdi32.DeleteDC(dcDest); return(hBitmapNew); }
/// <summary> /// Gets Image object containing screen shot /// </summary> /// <param name="handle">The handle to the window. /// <returns></returns> public void CaptureScreenshot(ref byte[] byteImage) { if (ProcessPtr == null) { byteImage = null; return; } var hdcSrc = User32.GetWindowDC(ProcessPtr); var windowRect = new User32.Rect(); User32.GetWindowRect(ProcessPtr, ref windowRect); var destinationPtr = Gdi32.CreateCompatibleDC(hdcSrc); var bitmapPtr = Gdi32.CreateCompatibleBitmap(hdcSrc, ScreenOptions.ScreenWidth, ScreenOptions.ScreenHeight); var hOld = Gdi32.SelectObject(destinationPtr, bitmapPtr); try { Gdi32.BitBlt(destinationPtr, 0, 0, ScreenOptions.ScreenWidth, ScreenOptions.ScreenHeight, hdcSrc, 0, 0, Gdi32.Srccopy); Gdi32.SelectObject(destinationPtr, hOld); using (var screenCaptureImage = Image.FromHbitmap(bitmapPtr)) using (var bitmap = new Bitmap(screenCaptureImage)) using (var memoryStream = new MemoryStream()) { screenCaptureImage.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Tiff); byteImage = new byte[memoryStream.Length]; byteImage = memoryStream.ToArray(); } } finally { Gdi32.DeleteDC(destinationPtr); User32.ReleaseDC(ProcessPtr, hdcSrc); Gdi32.DeleteObject(bitmapPtr); Gdi32.DeleteObject(hOld); } }
/// <summary> /// Creates bitmap by image pointer /// </summary> /// <param name="ptr"></param> /// <returns></returns> public static Bitmap GetImage(IntPtr ptr) { SIZE size; IntPtr hBitmap; IntPtr hDC = user32.GetDC(ptr); IntPtr hMemDC = Gdi32.CreateCompatibleDC(hDC); size.cx = user32.GetSystemMetrics(user32.SM_CXSCREEN); size.cy = user32.GetSystemMetrics(user32.SM_CYSCREEN); hBitmap = Gdi32.CreateCompatibleBitmap(hDC, size.cx, size.cy); if (hBitmap != IntPtr.Zero) { IntPtr hOld = (IntPtr)Gdi32.SelectObject(hMemDC, hBitmap); Gdi32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, Gdi32.SRCCOPY); Gdi32.SelectObject(hMemDC, hOld); Gdi32.DeleteDC(hMemDC); user32.ReleaseDC(ptr, hDC); Bitmap bmp = Image.FromHbitmap(hBitmap); Gdi32.DeleteObject(hBitmap); GC.Collect(); return(bmp); } return(null); }
/// <summary> /// 根据窗口名称截图 /// </summary> /// <param name="windowName">窗口名称</param> /// <returns></returns> public static Image ByName(string windowName) { IntPtr handle = User32.FindWindow(null, windowName); IntPtr hdcSrc = User32.GetWindowDC(handle); User32.RECT windowRect = new User32.RECT(); User32.GetWindowRect(handle, ref windowRect); int width = windowRect.right - windowRect.left; int height = windowRect.bottom - windowRect.top; IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc); IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height); IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap); Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, Gdi32.SRCCOPY); Gdi32.SelectObject(hdcDest, hOld); Gdi32.DeleteDC(hdcDest); User32.ReleaseDC(handle, hdcSrc); Image img = Image.FromHbitmap(hBitmap); Gdi32.DeleteObject(hBitmap); return(img); }
virtual public Bitmap Dc2Bmp(IntPtr hWnd, int Bit) { IntPtr wndHDC = GetDC(hWnd); IntPtr capHDC = Gdi32.CreateCompatibleDC(wndHDC); HBITMAP capBMP = Gdi32.CreateCompatibleBitmap(wndHDC, Size.Width, Size.Height); if (capBMP == IntPtr.Zero) { ReleaseDC(hWnd, wndHDC); Gdi32.DeleteDC(capHDC); return(null); } IntPtr prvHDC = (IntPtr)Gdi32.SelectObject(capHDC, capBMP); Gdi32.BitBlt(capHDC, 0, 0, Size.Width, Size.Height, wndHDC, Rect.X, Rect.Y, Bit); // managed: CompositeModeGDI.SRCCOPY Gdi32.SelectObject(capHDC, prvHDC); Bitmap bmp = System.Drawing.Image.FromHbitmap(capBMP); ReleaseDC(hWnd, wndHDC); // release window context Gdi32.DeleteDC(capHDC); // delete capture context Gdi32.DeleteObject(capBMP); // delete capture bitmap return(bmp); // return bitmap }
public IEnumerable <Image> Record() { recording = true; IntPtr hDesk = User32.GetDesktopWindow(); IntPtr hdcSrc = User32.GetWindowDC(hDesk); User32.GetWindowRect(hDesk, out RECT rect); int w = rect.Width; int h = rect.Height; IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc); IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, w, h); IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap); AsyncThread.Start(CalcFPS); while (recording) { Gdi32.BitBlt(hdcDest, 0, 0, w, h, hdcSrc, 0, 0, Constants.SRCCOPY); //Gdi32.SelectObject(hdcDest, hOld); yield return(Image.FromHbitmap(hBitmap)); ImageCount += 1; //Gdi32.DeleteObject(hBitmap); //hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, w, h); //hOld = Gdi32.SelectObject(hdcDest, hBitmap); } Gdi32.DeleteDC(hdcDest); User32.ReleaseDC(hDesk, hdcSrc); Gdi32.DeleteObject(hBitmap); }
public static Bitmap CreateBitmapFromGraphics(Graphics source, Rectangle bounds) { if (source == null) { throw new ArgumentNullException("source"); } IntPtr hDCSource = source.GetHdc(); IntPtr hDCDestination = Gdi32.CreateCompatibleDC(hDCSource); IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hDCSource, bounds.Width, bounds.Height); Gdi32.SelectObject(hDCDestination, hBitmap); Gdi32.BitBlt(hDCDestination, bounds.X, bounds.Y, bounds.Width, bounds.Height, hDCSource, bounds.X, bounds.Y, WinGdi.SRCCOPY); Bitmap bitmap = Bitmap.FromHbitmap(hBitmap); Gdi32.DeleteObject(hDCDestination); Gdi32.DeleteObject(hBitmap); source.ReleaseHdc(hDCSource); return(bitmap); }
void IconPanelPaint(object sender, PaintEventArgs e) { const int drawOffset = 1; if (maskBitmap != null) { IntPtr destDC = e.Graphics.GetHdc(); { // AND blitting IntPtr memDC = Gdi32.CreateCompatibleDC(destDC); IntPtr srcHBitmap = maskBitmap.GetHbitmap(); IntPtr oldHBitmap = Gdi32.SelectObject(memDC, srcHBitmap); Gdi32.BitBlt(destDC, drawOffset, drawOffset, iconSize.Width, iconSize.Height, memDC, 0, 0, Gdi32.SRCAND); // TODO: review if the objects get destroyed correctly Gdi32.SelectObject(memDC, oldHBitmap); Gdi32.DeleteObject(srcHBitmap); Gdi32.DeleteDC(memDC); Gdi32.DeleteDC(oldHBitmap); } { // XOR blitting IntPtr memDC = Gdi32.CreateCompatibleDC(destDC); IntPtr srcHBitmap = bitmap.GetHbitmap(); IntPtr oldHBitmap = Gdi32.SelectObject(memDC, srcHBitmap); Gdi32.BitBlt(destDC, drawOffset, drawOffset, iconSize.Width, iconSize.Height, memDC, 0, 0, Gdi32.SRCINVERT); Gdi32.SelectObject(memDC, oldHBitmap); Gdi32.DeleteObject(srcHBitmap); Gdi32.DeleteDC(memDC); Gdi32.DeleteDC(oldHBitmap); } Gdi32.DeleteDC(destDC); } else if (bitmap != null) { e.Graphics.DrawImageUnscaled(bitmap, drawOffset, drawOffset); } }
public override Mat ExecuteCaptureWindow(IntPtr hWnd) { var windowDc = User32.GetWindowDC(hWnd); var windowSize = GetWindowSize(hWnd); var width = windowSize.Width; var height = windowSize.Height; var memDc = Gdi32.CreateCompatibleDC(windowDc); var memBmp = Gdi32.CreateCompatibleBitmap(windowDc, width, height); var oldMemBmp = Gdi32.SelectObject(memDc, memBmp); var result = Gdi32.BitBlt(memDc.DangerousGetHandle(), 0, 0, width, height, windowDc.DangerousGetHandle(), 0, 0, (int)TernaryRasterOperations.SRCCOPY); Mat mat = null; var bytes = new byte[width * height * 3]; //获取位图像素RGB数据 if (result) { var bitmapInfo = new BITMAPINFOHEADER() { biWidth = width, biHeight = -height, biPlanes = 1, biBitCount = 24, biCompression = BitmapCompressionMode.BI_RGB }; bitmapInfo.Init(); Gdi32Extension.GetDIBits(memDc.DangerousGetHandle(), memBmp, 0, (uint)height, bytes, ref bitmapInfo, DIB_Color_Mode.DIB_RGB_COLORS); mat = new Mat(height, width, MatType.CV_8UC3, bytes); } Gdi32.SelectObject(memDc, oldMemBmp); Gdi32.DeleteObject(memBmp); Gdi32.DeleteDC(memDc); User32.ReleaseDC(hWnd, windowDc.HWnd); return(mat); }
/// <summary> /// Renders the tab thumbnail (<paramref name="image" />) using the given dimensions and coordinates and blends it properly with the underlying desktop elements /// </summary> /// <param name="image">Thumbnail to display</param> /// <param name="opacity">Opacity that <paramref name="image"/> should be displayed with</param> /// <param name="width">Width of <paramref name="image"/></param> /// <param name="height">Height of <paramref name="image"/></param> /// <param name="position">Screen position that <paramref name="image"/> should be displayed at</param> public void UpdateWindow(Bitmap image, byte opacity, int width, int height, POINT position) { IntPtr windowHandle = User32.GetWindowDC(Handle); IntPtr deviceContextHandle = Gdi32.CreateCompatibleDC(windowHandle); IntPtr bitmapHandle = image.GetHbitmap(Color.FromArgb(0)); IntPtr oldBitmapHandle = Gdi32.SelectObject(deviceContextHandle, bitmapHandle); SIZE size = new SIZE { cx = 0, cy = 0 }; POINT destinationPosition = new POINT { x = 0, y = 0 }; if (width == -1 || height == -1) { // No width and height specified, use the size of the image size.cx = image.Width; size.cy = image.Height; } else { // Use whichever size is smallest, so that the image will be clipped if necessary size.cx = Math.Min(image.Width, width); size.cy = Math.Min(image.Height, height); } // Set the opacity and blend the image with the underlying desktop elements using User32.UpdateLayeredWindow BLENDFUNCTION blendFunction = new BLENDFUNCTION { BlendOp = Convert.ToByte((int)AC.AC_SRC_OVER), SourceConstantAlpha = opacity, AlphaFormat = Convert.ToByte((int)AC.AC_SRC_ALPHA), BlendFlags = 0 }; User32.UpdateLayeredWindow(Handle, windowHandle, ref position, ref size, deviceContextHandle, ref destinationPosition, 0, ref blendFunction, ULW.ULW_ALPHA); Gdi32.SelectObject(deviceContextHandle, oldBitmapHandle); Gdi32.DeleteObject(bitmapHandle); Gdi32.DeleteDC(deviceContextHandle); User32.ReleaseDC(Handle, windowHandle); }
//通过句柄来获取图片 public Image GetPic_ByHwnd(IntPtr hWnd, User32.RECT rect) { // 根据句柄获取设备上下文句柄 IntPtr hdcSrc = User32.GetWindowDC(hWnd); // 创建与指定设备兼容的存储器设备上下文(DC) IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc); //设置长宽 int width = rect.right - rect.left; int height = rect.bottom - rect.top; //图片长宽和起点赋值 this.width = width; this.height = height; // 使用bitmap对象来存设备上下文数据 IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height); // 选择bitmap对象到指定设备上下文环境中 IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap); // 执行与指定源设备上下文的像素矩形对应的颜色数据的位块传输到目标设备上下文。 Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, Gdi32.SRCCOPY); // 恢复设备上下文环境 Gdi32.SelectObject(hdcDest, hOld); // 释放句柄 Gdi32.DeleteDC(hdcDest); User32.ReleaseDC(hWnd, hdcSrc); // 将数据流转换成图 Image img = Image.FromHbitmap(hBitmap); // 释放bitmap对象 Gdi32.DeleteObject(hBitmap); return(img); }
public static byte[] Capture(Screen monitor) { byte[] imageBytes = null; try { Bitmap resultBmp = null; Rectangle monitorRect = monitor.Bounds; HWND desktopWindow = User32.GetDesktopWindow(); HDC windowDc = User32.GetWindowDC(desktopWindow); HDC memDc = Gdi32.CreateCompatibleDC(windowDc); var bitmap = Gdi32.CreateCompatibleBitmap(windowDc, monitorRect.Width, monitorRect.Height); var oldBitmap = Gdi32.SelectObject(memDc, bitmap); bool result = Gdi32.BitBlt(memDc, 0, 0, monitorRect.Width, monitorRect.Height, windowDc, monitorRect.X, monitorRect.Y, Gdi32.RasterOperationMode.SRCCOPY); User32.CURSORINFO pci = new(); pci.cbSize = (uint)Marshal.SizeOf(typeof(User32.CURSORINFO)); if (User32.GetCursorInfo(ref pci)) { if (pci.flags == User32.CursorState.CURSOR_SHOWING) { User32.DrawIcon(memDc, pci.ptScreenPos.X - monitorRect.X, pci.ptScreenPos.Y - monitorRect.Y, pci.hCursor.DangerousGetHandle()); } } if (result) { resultBmp = bitmap.ToBitmap(); } Gdi32.SelectObject(memDc, oldBitmap); Gdi32.DeleteObject(bitmap); Gdi32.DeleteDC(memDc); User32.ReleaseDC(desktopWindow, windowDc); var shrunkImage = resultBmp.GetThumbnailImage(320, 240, null, IntPtr.Zero); resultBmp.Dispose(); var cloned = shrunkImage.ConvertPixelFormatAsync(PixelFormat.Format8bppIndexed, OptimizedPaletteQuantizer.Octree(), ErrorDiffusionDitherer.FloydSteinberg, new TaskConfig()).GetAwaiter().GetResult(); shrunkImage.Dispose(); short[] colors = new short[256]; var pal = (Color[])cloned.Palette.Entries.Clone(); Parallel.For(0, cloned.Palette.Entries.Length, i => { colors[i] = ConvertColor(pal[i].R, pal[i].G, pal[i].B); }); imageBytes = new byte[colors.Length * sizeof(short) + cloned.Width * cloned.Height]; Buffer.BlockCopy(colors, 0, imageBytes, 0, colors.Length * sizeof(short)); BitmapData imageData = cloned.LockBits(new Rectangle(0, 0, cloned.Width, cloned.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed); Marshal.Copy(imageData.Scan0, imageBytes, colors.Length * sizeof(short), cloned.Width * cloned.Height); cloned.UnlockBits(imageData); cloned.Dispose(); _errorCount = 0; } catch (Exception ex) { _errorCount++; return(CaptureErr(monitor, ex)); } return(imageBytes); }
private static Monitor ParseMonitor(IntPtr monitorHandle, IntPtr hdc) { var info = new MonitorInfoEx(); //TODO: MonitorInfo not getting filled with data. var a = User32.GetMonitorInfo(new HandleRef(null, monitorHandle), info); var name = new string(info.szDevice).TrimEnd((char)0); var monitor = new Monitor { Handle = monitorHandle, Name = name, FriendlyName = name, NativeBounds = new Rect(info.rcMonitor.Left, info.rcMonitor.Top, info.rcMonitor.Right - info.rcMonitor.Left, info.rcMonitor.Bottom - info.rcMonitor.Top), Bounds = new Rect(info.rcMonitor.Left, info.rcMonitor.Top, info.rcMonitor.Right - info.rcMonitor.Left, info.rcMonitor.Bottom - info.rcMonitor.Top), WorkingArea = new Rect(info.rcWork.Left, info.rcWork.Top, info.rcWork.Right - info.rcWork.Left, info.rcWork.Bottom - info.rcWork.Top), IsPrimary = (info.dwFlags & Constants.MonitorinfoPrimary) != 0 }; #region Extra details try { var display = new DisplayDevices(true); for (uint id = 0; User32.EnumDisplayDevices(null, id, ref display, 0); id++) { var found = display.DeviceName == monitor.Name; var adapter = display.DeviceString; User32.EnumDisplayDevices(display.DeviceName, id, ref display, 0); if (!found) { continue; } monitor.AdapterName = adapter; monitor.FriendlyName = string.IsNullOrWhiteSpace(display.DeviceString) ? LocalizationHelper.Get("S.Recorder.Screen.Name.Internal") : display.DeviceString == "Generic PnP Monitor" ? LocalizationHelper.Get("S.Recorder.Screen.Name.Generic") : display.DeviceString; break; } } catch (Exception ex) { LogWriter.Log(ex, "Impossible to get extra details of screen."); } #endregion #region Screen DPI try { ShCore.GetDpiForMonitor(monitorHandle, DpiTypes.Effective, out var aux, out _); monitor.Dpi = aux > 0 ? (int)aux : 96; } catch (Exception ex) { LogWriter.Log(ex, "Impossible to detect screen DPI."); try { var h = Gdi32.CreateCompatibleDC(IntPtr.Zero); monitor.Dpi = Gdi32.GetDeviceCaps(h, (int)DeviceCaps.LogPixelsX); Gdi32.DeleteDC(h); } catch (Exception e) { LogWriter.Log(e, "Error getting fallback of screen DPI."); } } #endregion return(monitor); }
private void CreateWindow(string className) { if (className == null) { throw new Exception("class_name is null"); } if (className == String.Empty) { throw new Exception("class_name is empty"); } _wndProcDelegate = CustomWndProc; gcHandle = GCHandle.Alloc(_wndProcDelegate); WNDCLASS windClass = new WNDCLASS { lpszClassName = className, lpfnWndProc = Marshal.GetFunctionPointerForDelegate(_wndProcDelegate) }; ushort classAtom = User32.RegisterClassW(ref windClass); int lastError = Marshal.GetLastWin32Error(); if (classAtom == 0 && lastError != ERROR_CLASS_ALREADY_EXISTS) { throw new Exception("Could not register window class"); } uint extendedStyle = (uint)( WindowExStyles.WS_EX_LEFT | WindowExStyles.WS_EX_LTRREADING | WindowExStyles.WS_EX_RIGHTSCROLLBAR | WindowExStyles.WS_EX_TOOLWINDOW); const uint style = (uint)( WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_POPUP); // Create window Handle = User32.CreateWindowExW( extendedStyle, className, className, style, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero ); if (Handle == IntPtr.Zero) { return; } var styles = (int)User32.GetWindowLongPtr(Handle, WindowLongFlags.GWL_EXSTYLE); //var owner = User32.GetWindow(_parentHandle, 4); //User32.SetWindowLong(Handle, GetWindowLongFlags.GWL_HWNDPARENT, owner); styles |= (int)(WindowExStyles.WS_EX_LAYERED | WindowExStyles.WS_EX_NOACTIVATE | WindowExStyles.WS_EX_NOPARENTNOTIFY); if (!_decorator.Resizable) { styles |= (int)WindowExStyles.WS_EX_TRANSPARENT; } User32.SetWindowLongPtr(Handle, WindowLongFlags.GWL_EXSTYLE, new IntPtr(styles)); _screenDC = User32.GetDC(IntPtr.Zero); _memDC = Gdi32.CreateCompatibleDC(_screenDC); D2D1.D2D1CreateFactory(FactoryType.SingleThreaded, out _d2dFactory); }
public static Bitmap?ToBitmap(this Graphics graphics, bool visibleClipOnly) { if (!OSUtils.IsWindows) { throw new PlatformNotSupportedException(Res.RequiresWindows); } if (graphics == null) { throw new ArgumentNullException(nameof(graphics), PublicResources.ArgumentNull); } if (visibleClipOnly && graphics.IsVisibleClipEmpty) { return(null); } Bitmap result; RectangleF visibleRect; int sourceLeft, sourceTop, targetWidth, targetHeight; GraphicsState state = graphics.Save(); try { // resetting the identity matrix so VisibleClipBounds will be correct graphics.Transform = new Matrix(); // obtaining size in pixels graphics.PageUnit = GraphicsUnit.Pixel; visibleRect = graphics.VisibleClipBounds; sourceLeft = (int)visibleRect.Left; sourceTop = (int)visibleRect.Top; targetWidth = (int)visibleRect.Width; targetHeight = (int)visibleRect.Height; // there is a source image: copying so transparency is preserved Image?imgSource = graphics.GetBackingImage(); if (imgSource != null) { if (imgSource is Metafile) { throw new NotSupportedException(Res.GraphicsExtensionsToBitmapMetafileNotSupported); } if (!visibleClipOnly) { return((Bitmap)imgSource.Clone()); } if (targetWidth == 0 || targetHeight == 0) { return(null); } result = new Bitmap(targetWidth, targetHeight, imgSource.PixelFormat); using IReadableBitmapData src = ((Bitmap)imgSource).GetReadableBitmapData(); using IWritableBitmapData dst = result.GetWritableBitmapData(); src.CopyTo(dst, new Rectangle(sourceLeft, sourceTop, targetWidth, targetHeight), Point.Empty); return(result); } } finally { graphics.Restore(state); } IntPtr dcSource = graphics.GetHdc(); if (!visibleClipOnly) { sourceLeft = 0; sourceTop = 0; // obtaining container Window IntPtr hwnd = User32.WindowFromDC(dcSource); if (hwnd != IntPtr.Zero) { //// Show in whole screen //RECT rect; //GetWindowRect(hwnd, out rect); // the full rect of self control on screen //// Show in screen //GetWindowRect(hwnd, out rect); //left = -rect.Left; //top = -rect.Top; //width = GetDeviceCaps(dcSource, DeviceCap.HORZRES); //height = GetDeviceCaps(dcSource, DeviceCap.VERTRES); //visibleRect.Offset(rect.Left, rect.Top); //// Show in parent control //IntPtr hwndParent = GetParent(hwnd); //if (hwndParent != IntPtr.Zero) //{ // RECT rectParent; // GetWindowRect(hwndParent, out rectParent); // left = rectParent.Left - rect.Left; // top = rectParent.Top - rect.Top; // width = rectParent.Right - rectParent.Left; // height = rectParent.Bottom - rectParent.Top; // visibleRect.Offset(-left, -top); //} //else // Show in container control Rectangle rect = User32.GetClientRect(hwnd); if (rect.Right < visibleRect.Right && rect.Bottom < visibleRect.Bottom) { // Visible rect is larger than client rect: calculating from full size. // This is usually the case when Graphics is created for nonclient area rect = User32.GetWindowRect(hwnd); } targetWidth = rect.Right - rect.Left; targetHeight = rect.Bottom - rect.Top; } else if (visibleRect.Location != Point.Empty) { // no window: surrounding symmetrically or max 100 px targetWidth = (int)(visibleRect.Right + Math.Min(visibleRect.Left, 100f)); targetHeight = (int)(visibleRect.Bottom + Math.Min(visibleRect.Top, 100f)); } } // the container control is too small if (targetWidth <= 0 || targetHeight <= 0) { graphics.ReleaseHdc(dcSource); return(null); } // creating a compatible bitmap IntPtr dcTarget = Gdi32.CreateCompatibleDC(dcSource); IntPtr hbmResult = Gdi32.CreateCompatibleBitmap(dcSource, targetWidth, targetHeight); Gdi32.SelectObject(dcTarget, hbmResult); // Copy content Gdi32.BitBlt(dcTarget, 0, 0, targetWidth, targetHeight, dcSource, sourceLeft, sourceTop); result = Image.FromHbitmap(hbmResult); //cleanup graphics.ReleaseHdc(dcSource); Gdi32.DeleteDC(dcTarget); Gdi32.DeleteObject(hbmResult); return(result); }
public static Image StretchImage( Image sourceImage, Point p, Rectangle zoomRegion, Size desiredSize ) { Image myImage = new Bitmap( desiredSize.Width, desiredSize.Height ); using ( Graphics g = Graphics.FromImage( myImage ) ) { // use the DrawImage method in the framework to achieve a // similar, but not as pixelated effect. // g.DrawImage( sourceImage, // new Rectangle( new Point( 0 ), desiredSize ), // zoomRegion, // GraphicsUnit.Pixel ); // we're dealing with memory device contexts here. first, a // device context for the screen is retrieved. this serves as the // handle to the device context. we then create a memory device // context that is compatible with the device context of the // screen (desktop). IntPtr hdc = User32.GetDC( IntPtr.Zero ); IntPtr memoryDC = Gdi32.CreateCompatibleDC( hdc ); // we retrieve a handle to the source bitmap object. this is // then used to select the bitmap into the memory device // context. IntPtr hBitmap = ( ( Bitmap ) sourceImage ).GetHbitmap(); IntPtr oldObject = Gdi32.SelectObject( memoryDC, hBitmap ); // Delete the object that was previously selected into the // memory device context (there is a default bitmap object // that is encapsulated by the returned object, so we need // to make sure we get rid of that, otherwise we'll have // gdi object leaks). Gdi32.DeleteObject( oldObject ); // the handle to the destination device context is retrieved. IntPtr destDeviceContext = g.GetHdc(); // the source bitmap is stretched and its bits are blitted to // the canvas represented by the destination device context. int result = Gdi32.StretchBlt( destDeviceContext, 0, 0, desiredSize.Width, desiredSize.Height, memoryDC, p.X, p.Y, zoomRegion.Width, zoomRegion.Height, RasterOperationCodes.SRCCOPY ); // error checking - StretchBlt returns non-zero on success. if ( result == 0 ) { // TODO: call GetLastError to dig down to the core of the problem. throw new ImageManipulationException( "There was a problem with the StretchBlt function call." ); } // release everything g.ReleaseHdc( destDeviceContext ); // clear the previously selected bitmap object from the memory // device context. Gdi32.DeleteObject( hBitmap ); // get rid of the memory device context. Gdi32.DeleteDC( memoryDC ); // return the device context to the device context pool. User32.ReleaseDC( IntPtr.Zero, hdc ); } // dispose the Graphics object return myImage; }
/// <summary> /// Renders the tabs and then calls <see cref="User32.UpdateLayeredWindow" /> to blend the tab content with the underlying window ( /// <see cref="_parentForm" />). /// </summary> /// <param name="cursorPosition">Current position of the cursor.</param> /// <param name="forceRedraw">Flag indicating whether a full render should be forced.</param> public void Render(Point cursorPosition, bool forceRedraw = false) { if (!IsDisposed && _parentForm.TabRenderer != null && _parentForm.WindowState != FormWindowState.Minimized && _parentForm.ClientRectangle.Width > 0) { cursorPosition = GetRelativeCursorPosition(cursorPosition); using (Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format32bppArgb)) { using (Graphics graphics = Graphics.FromImage(bitmap)) { DrawTitleBarBackground(graphics); // Since classic mode themes draw over the *entire* titlebar, not just the area immediately behind the tabs, we have to offset the tabs // when rendering in the window Point offset = _parentForm.WindowState != FormWindowState.Maximized && DisplayType == DisplayType.Classic ? new Point(0, SystemInformation.CaptionButtonSize.Height) : _parentForm.WindowState != FormWindowState.Maximized ? new Point(0, SystemInformation.VerticalResizeBorderThickness - SystemInformation.BorderSize.Height) : new Point(0, 0); // Render the tabs into the bitmap _parentForm.TabRenderer.Render(_parentForm.Tabs, graphics, offset, cursorPosition, forceRedraw); // Cut out a hole in the background so that the control box on the underlying window can be shown if (DisplayType == DisplayType.Classic && (_parentForm.ControlBox || _parentForm.MaximizeBox || _parentForm.MinimizeBox)) { int boxWidth = 0; if (_parentForm.ControlBox) { boxWidth += SystemInformation.CaptionButtonSize.Width; } if (_parentForm.MinimizeBox) { boxWidth += SystemInformation.CaptionButtonSize.Width; } if (_parentForm.MaximizeBox) { boxWidth += SystemInformation.CaptionButtonSize.Width; } CompositingMode oldCompositingMode = graphics.CompositingMode; graphics.CompositingMode = CompositingMode.SourceCopy; graphics.FillRectangle( new SolidBrush(Color.Transparent), Width - boxWidth, 0, boxWidth, SystemInformation.CaptionButtonSize.Height); graphics.CompositingMode = oldCompositingMode; } IntPtr screenDc = User32.GetDC(IntPtr.Zero); IntPtr memDc = Gdi32.CreateCompatibleDC(screenDc); IntPtr oldBitmap = IntPtr.Zero; IntPtr bitmapHandle = IntPtr.Zero; try { // Copy the contents of the bitmap into memDc bitmapHandle = bitmap.GetHbitmap(Color.FromArgb(0)); oldBitmap = Gdi32.SelectObject(memDc, bitmapHandle); SIZE size = new SIZE { cx = bitmap.Width, cy = bitmap.Height }; POINT pointSource = new POINT { x = 0, y = 0 }; POINT topPos = new POINT { x = Left, y = Top }; BLENDFUNCTION blend = new BLENDFUNCTION { // We want to blend the bitmap's content with the screen content under it BlendOp = Convert.ToByte((int)AC.AC_SRC_OVER), BlendFlags = 0, // Follow the parent forms' opacity level SourceConstantAlpha = (byte)(_parentForm.Opacity * 255), // We use the bitmap's alpha channel for blending instead of a pre-defined transparency key AlphaFormat = Convert.ToByte((int)AC.AC_SRC_ALPHA) }; // Blend the tab content with the underlying content if (!User32.UpdateLayeredWindow( Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, ULW.ULW_ALPHA)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Error while calling UpdateLayeredWindow()."); } } // Clean up after ourselves finally { User32.ReleaseDC(IntPtr.Zero, screenDc); if (bitmapHandle != IntPtr.Zero) { Gdi32.SelectObject(memDc, oldBitmap); Gdi32.DeleteObject(bitmapHandle); } Gdi32.DeleteDC(memDc); } } } } }