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);
        }
示例#2
0
    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);
    }
示例#3
0
        /// <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);
                    }
        }
示例#4
0
        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);
        }
示例#5
0
    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);
    }
示例#6
0
 private static void SaveImageAs(int hBitmap, Stream str, ImageFormat imageFormat)
 {
     Image.FromHbitmap(new IntPtr(hBitmap)).Save(str, imageFormat);
 }
示例#7
0
        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);
        }
示例#8
0
        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;
            }
        }