Пример #1
0
        private Bitmap GetDX11ScreenShot()
        {
            try
            {
                screenShot = null;
                screenShot = new Bitmap(WIDTH, HEIGHT, this.pixelFormat);
                if (dx11DuplicatedOutput != null)
                {
                    dx11DuplicatedOutput.AcquireNextFrame(NEXT_FRAME_TIMEOUT,
                                                          out dx11DuplFrameInfo, out dx11ScreenResource);

                    dx11Device.ImmediateContext
                    .CopyResource(dx11ScreenResource.QueryInterface <SharpDX.Direct3D11.Resource>(),
                                  dx11ScreenTexture);

                    // cast from texture to surface, so we can access its bytes
                    dx11ScreenSurface = dx11ScreenTexture.QueryInterface <SharpDX.DXGI.Surface>();
                    // map the resource to access it
                    dx11Map = dx11ScreenSurface.Map(SharpDX.DXGI.MapFlags.Read);
                    bmpData = screenShot.LockBits(boundsRect, ImageLockMode.WriteOnly, screenShot.PixelFormat);
                    var sourcePtr = dx11Map.DataPointer;
                    var destPtr   = bmpData.Scan0;
                    for (int y = 0; y < HEIGHT; y++)
                    {
                        // Copy a single line
                        Utilities.CopyMemory(destPtr, sourcePtr, ARGB_WIDTH);
                        // Advance pointers
                        sourcePtr = IntPtr.Add(sourcePtr, dx11Map.Pitch);
                        destPtr   = IntPtr.Add(destPtr, bmpData.Stride);
                    }

                    dx11Device.ImmediateContext.UnmapSubresource(dx11ScreenTexture, 0);
                    screenShot.UnlockBits(bmpData);
                    dx11ScreenSurface.Unmap();
                    dx11ScreenSurface.Dispose();
                    dx11ScreenResource.Dispose();
                    dx11DuplicatedOutput.ReleaseFrame();
                }
                else
                {
                    return(screenShot = null);
                }

                dx11ScreenSurface = null;
                bmpData           = null;
                GC.Collect();

                return(screenShot);
            }
            catch (SharpDX.SharpDXException e)
            {
                if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code)
                {
                    //screen does not changed
                    LdpLog.Warning("DX11 surface timeout.. Recursion is coming:)");
                    return(GetDX11ScreenShot());
                }
                else
                {
                    return(screenShot = null);
                }
            }
            catch (Exception ex)
            {
                LdpLog.Error("GetDX11ScreenShot\n" + ex.Message);
                return(screenShot = null);
            }
        }
Пример #2
0
        public Bitmap getScreenDX()
        {
            if (System.Windows.Forms.Screen.AllScreens[0].Bounds.Width != LEDSetup.SCREEN_W)
            {
                return(null);
            }
            try
            {
                SharpDX.DXGI.Resource           screenResource;
                OutputDuplicateFrameInformation duplicateFrameInformation;

                // Try to get duplicated frame within given time
                duplicatedOutput.AcquireNextFrame(1000, out duplicateFrameInformation, out screenResource);

                // copy resource into memory that can be accessed by the CPU
                using (var screenTexture2D = screenResource.QueryInterface <Texture2D>())
                    device.ImmediateContext.CopyResource(screenTexture2D, screenTexture);

                // Get the desktop capture texture
                var mapSource = device.ImmediateContext.MapSubresource(screenTexture, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None);

                // Create Drawing.Bitmap
                var bitmap     = new System.Drawing.Bitmap(LEDSetup.SCREEN_W, LEDSetup.SCREEN_H, PixelFormat.Format32bppArgb);
                var boundsRect = new System.Drawing.Rectangle(0, 0, LEDSetup.SCREEN_W, LEDSetup.SCREEN_H);

                // Copy pixels from screen capture Texture to GDI bitmap
                var mapDest   = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
                var sourcePtr = mapSource.DataPointer;
                var destPtr   = mapDest.Scan0;
                for (int y = 0; y < LEDSetup.SCREEN_H; y++)
                {
                    // Copy a single line
                    Utilities.CopyMemory(destPtr, sourcePtr, LEDSetup.SCREEN_W * 4);

                    // Advance pointers
                    sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
                    destPtr   = IntPtr.Add(destPtr, mapDest.Stride);
                }

                // Release source and dest locks
                bitmap.UnlockBits(mapDest);
                device.ImmediateContext.UnmapSubresource(screenTexture, 0);

                // Save the output
                //bitmap.Save(outputFileName, ImageFormat.Png);

                // Capture done

                screenResource.Dispose();
                duplicatedOutput.ReleaseFrame();

                invalid_calls = 0;
                return(bitmap);
            }
            catch (SharpDXException e)
            {
                if (e.ResultCode.Code != SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code)// && e.ResultCode != SharpDX.DXGI.ResultCode.InvalidCall.Result.Code)
                {
                    if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.AccessLost.Result.Code)
                    {
                        Logger.QueueLine("Device access lost, reinitializing duplication");
                        setupDX();
                        System.Threading.Thread.Sleep(200);
                    }
                    else if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.DeviceRemoved.Code)
                    {
                        Logger.QueueLine("Device removed, reinitializing duplication");
                        setupDX();
                        System.Threading.Thread.Sleep(200);
                    }
                    else if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.InvalidCall.Code)
                    {
                        invalid_calls++;
                        if (invalid_calls >= 10)
                        {
                            Logger.QueueLine("Too many invalid calls, reinitializing duplication");
                            setupDX();
                        }
                        System.Threading.Thread.Sleep(200);
                    }
                    else
                    {
                        throw e;
                    }
                }
            }
            catch (Exception e)
            {
            }
            return(null);
        }