コード例 #1
0
        public void StartCapture(IntPtr hWnd, Device device, Factory factory)
        {
            var capturePicker = new GraphicsCapturePicker();

            // ReSharper disable once PossibleInvalidCastException
            // ReSharper disable once SuspiciousTypeConversion.Global
            var initializer = (IInitializeWithWindow)(object)capturePicker;

            initializer.Initialize(hWnd);

            _captureItem = capturePicker.PickSingleItemAsync().AsTask().Result;
            if (_captureItem == null)
            {
                return;
            }

            _captureItem.Closed += CaptureItemOnClosed;

            var hr = NativeMethods.CreateDirect3D11DeviceFromDXGIDevice(device.NativePointer, out var pUnknown);

            if (hr != 0)
            {
                StopCapture();
                return;
            }

            var winrtDevice = (IDirect3DDevice)Marshal.GetObjectForIUnknown(pUnknown);

            Marshal.Release(pUnknown);

            _captureFramePool = Direct3D11CaptureFramePool.Create(winrtDevice, DirectXPixelFormat.B8G8R8A8UIntNormalized, 2, _captureItem.Size);
            _captureSession   = _captureFramePool.CreateCaptureSession(_captureItem);
            _captureSession.StartCapture();
            IsCapturing = true;
        }
コード例 #2
0
        private async void RecordButton_Click(object sender, RoutedEventArgs e)
        {
            var button = (AppBarToggleButton)sender;

            if (button.IsChecked.Value)
            {
                var picker = new GraphicsCapturePicker();
                var item   = await picker.PickSingleItemAsync();

                if (item == null)
                {
                    button.IsChecked = false;
                    return;
                }

                var file = await PickVideoAsync();

                if (file == null)
                {
                    button.IsChecked = false;
                    return;
                }

                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                    using (_encoder = new Encoder(_device, item))
                    {
                        await _encoder.EncodeAsync(stream);
                    }
            }
            else
            {
                _encoder?.Dispose();
            }
        }
コード例 #3
0
        /// <summary>
        ///     Initializes a <see cref="GraphicsCapturePicker" /> with a window.
        /// </summary>
        /// <param name="picker">The <see cref="GraphicsCapturePicker" /> to initialize.</param>
        /// <param name="hWnd">The handle of the window to initialize the picker with.</param>
        internal static void SetWindow(this GraphicsCapturePicker picker, IntPtr hWnd)
        {
            // Cast via object as direct cast is not supported for imported interface
            var interop = picker as object as IInitializeWithWindow;

            interop?.Initialize(hWnd);
        }
コード例 #4
0
        public static void SetWindow(this GraphicsCapturePicker picker, IntPtr hwnd)
        {
            //var interop = picker.As<IInitializeWithWindow>();
            var interop = (IInitializeWithWindow)(object)picker;

            interop.Initialize(hwnd);
        }
コード例 #5
0
        public MainWindow()
        {
            InitializeComponent();

#if DEBUG
            // Force graphicscapture.dll to load.
            var picker = new GraphicsCapturePicker();
#endif
        }
コード例 #6
0
        public async Task <GraphicsCaptureItemWrapper> UserSelectAsync(IntPtr hwnd)
        {
            var picker = new GraphicsCapturePicker();

            picker.SetWindow(hwnd);
            var item = await picker.PickSingleItemAsync();

            return(item != null ? new GraphicsCaptureItemWrapper(item, "UserSelect") : null);
        }
コード例 #7
0
        public async Task StartCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            // The item may be null if the user dismissed the
            // control without making a selection or hit Cancel.
            if (item != null)
            {
                StartCaptureInternal(item);
            }
        }
コード例 #8
0
        private async void CaptureButton_Click(object sender, RoutedEventArgs e)
        {
            StopCapture();

            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                StartCapture(item);
            }
        }
コード例 #9
0
        private async Task StartPickerCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();

            picker.SetWindow(hwnd);
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            if (item != null)
            {
                sample.StartCaptureFromItem(item);
            }
        }
コード例 #10
0
        public async Task StartCaptureAsync()
        {
            // 让用户选择哪个应用
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            // 如果用户有选择一个应用那么这个属性不为空
            if (item != null)
            {
                StartCaptureInternal(item);
            }
        }
コード例 #11
0
        public async Task StartCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            if (item != null)
            {
                _captureFolder = await _setupCpatureFolder();

                _startCaptureInternal(item);
            }
        }
コード例 #12
0
        private async Task StartRecordingAsync()
        {
            GraphicsCapturePicker pick = new GraphicsCapturePicker();
            var recordedfield          = await pick.PickSingleItemAsync();

            CoreWindow window = CoreApplication.MainView.CoreWindow;

            await window.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
            {
                await new ScreenRecord().Record(recordedfield);
            });
        }
コード例 #13
0
ファイル: CallsService.cs プロジェクト: UnigramDev/Unigram
        public async Task <VoipVideoCapture> ToggleCapturingAsync(VoipCaptureType type)
        {
            void Disable()
            {
                if (_capturer != null)
                {
                    _capturer.SetOutput(null);
                    _manager.SetVideoCapture(null);

                    _capturer.Dispose();
                    _capturer = null;
                }
            }

            if (type == VoipCaptureType.None)
            {
                Disable();
            }
            else if (type == VoipCaptureType.Video && _capturer is not VoipVideoCapture)
            {
                Disable();

                if (_manager == null)
                {
                    return(null);
                }

                _capturer = new VoipVideoCapture(await _videoWatcher.GetAndUpdateAsync());
                _manager?.SetVideoCapture(_capturer);
            }
            else if (type == VoipCaptureType.Screencast && _capturer is not VoipScreenCapture)
            {
                Disable();

                if (_manager == null || !GraphicsCaptureSession.IsSupported())
                {
                    return(null);
                }

                var picker = new GraphicsCapturePicker();
                var item   = await picker.PickSingleItemAsync();

                if (item == null || _manager == null)
                {
                    return(null);
                }

                _capturer = new VoipScreenCapture(item);
                _manager?.SetVideoCapture(_capturer);
            }

            return(_capturer);
        }
コード例 #14
0
        public async Task CaptureScreenshotAsync(string filename)
        {
            this.fileName = filename;
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            // The item may be null if the user dismissed the
            // control without making a selection or hit Cancel.
            if (item != null)
            {
                await StartCaptureInternal(item);
            }
        }
コード例 #15
0
        public MainWindow()
        {
            InitializeComponent();

#if DEBUG
            // Force graphicscapture.dll to load.
            var picker = new GraphicsCapturePicker();
#endif

            var offscreenWindow = new OffscreenWindow();
            offscreenWindow.Left = 10000;
            offscreenWindow.Show();
        }
コード例 #16
0
        public async Task PickScreen()
        {
            GraphicsCapturePicker picker = new GraphicsCapturePicker();
            GraphicsCaptureItem   item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                if (simpleRecorder != null)
                {
                    simpleRecorder.gcitem = item;
                    ScreenTextBox.Text    = item.DisplayName;
                }
            }
        }
コード例 #17
0
        private async Task StartPickerCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();

            picker.SetWindow(_hwnd);
            var item = await picker.PickSingleItemAsync();

            if (item != null)
            {
                var dc = this.DataContext as MainViewModel;
                dc.TargetName.Value = item.DisplayName;
                StartCapture(item);
            }
        }
コード例 #18
0
        public async Task StartCaptureAsync()
        {
            _canvasDevice = CanvasDevice.GetSharedDevice();
            // The GraphicsCapturePicker follows the same pattern the
            // file pickers do.
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            // The item may be null if the user dismissed the
            // control without making a selection or hit Cancel.
            if (item != null)
            {
                StartCaptureInternal(item);
            }
        }
コード例 #19
0
        private async Task StartCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                _capture = new Capture(_device, item);

                var surface = _capture.CreateSurface(_compositor);
                _brush.Surface = surface;

                _capture.StartCapture();
            }
        }
コード例 #20
0
        public async Task StartCaptureAsync()
        {
            composition = new MediaComposition();
            // The GraphicsCapturePicker follows the same pattern the
            // file pickers do.
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            // The item may be null if the user dismissed the
            // control without making a selection or hit Cancel.
            if (item != null)
            {
                StopButton.Visibility = Visibility.Visible;
                // We'll define this method later in the document.
                StartCaptureInternal(item);
            }
        }
コード例 #21
0
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                StartPreview(item);
            }
            else
            {
                StopPreview();
            }



            _item = item;
        }
コード例 #22
0
        private async Task StartRecording()
        {
            Debug.Assert(!IsRecording);

            var pick        = new GraphicsCapturePicker();
            var captureItem = await pick.PickSingleItemAsync();

            if (captureItem != null)
            {
                _recorderOutput = ApplicationData.Current.TemporaryFolder;

                await ClearFolder(_recorderOutput);

                _sw.Restart();
                _elapsedUpdateTimer.Start();

                _recorder.Start(captureItem, _recorderOutput);
            }

            IsRecording = true;
        }
コード例 #23
0
        public async Task StartCaptureAsyncInternal()
        {
            Logger.Debug("Screen", "StartCaptureAsyncInternal");

            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            if (item == null)
            {
                return;
            }

            StopCaptureInternal();

            this.item     = item;
            this.lastSize = item.Size;

            screenCaptureTask = CreateScreenCaptureTask();
            screenCaptureTask.Start();

            if (canvasDevice == null)
            {
                canvasDevice = new CanvasDevice();
            }

            framePool = Direct3D11CaptureFramePool.Create(
                canvasDevice,
                DirectXPixelFormat.B8G8R8A8UIntNormalized,
                2,
                item.Size);

            framePool.FrameArrived += FramePool_FrameArrived;
            item.Closed            += (s, a) =>
            {
                StopCaptureInternal();
            };
            session = framePool.CreateCaptureSession(item);
            session.StartCapture();
        }
コード例 #24
0
ファイル: MainPage.xaml.cs プロジェクト: arxalex/VidCapApp
        public async Task StartCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item;

            if (saveitem == null)
            {
                item = await picker.PickSingleItemAsync();
            }
            else
            {
                item = saveitem;
            }
            if (item != null)
            {
                lnd.DisplayHeight = item.Size.Height;
                lnd.DisplayWidth  = item.Size.Width;
                lnd.Update();
                Update();
                WriteSittings();
                StartCaptureInternal(item);
            }
        }
コード例 #25
0
        private async Task PrepareCapture()
        {
            lbInfo.Content = "상태 : 윈도우 선택중";
            var picker = new GraphicsCapturePicker();

            picker.SetWindow(hwnd);
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            if (item != null)
            {
                IntPtr hWnd = GethWnd(item.DisplayName);

                if (hWnd == IntPtr.Zero)
                {
                    if (MessageBox.Show("해당 윈도우는 캡쳐할 수 없습니다" + System.Environment.NewLine + "윈도우가 활성화 되어 있는지 확인해 주세요", "오류", MessageBoxButton.OK) == MessageBoxResult.OK)
                    {
                        Close();
                    }
                }
                else
                {
                    item.Closed += (s, a) =>
                    {
                        StopCapture();
                    };
                    sample.StartCaptureFromItem(item, hWnd);
                    callback();

                    lbInfo.Content = "상태 : 캡쳐 중 - " + item.DisplayName;
                }
            }
            else
            {
                Close();
            }
        }
コード例 #26
0
        private async void ToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            var button = (ToggleButton)sender;

            // Get our encoder properties
            var frameRate     = uint.Parse(((string)FrameRateComboBox.SelectedItem).Replace("fps", ""));
            var quality       = (VideoEncodingQuality)Enum.Parse(typeof(VideoEncodingQuality), (string)QualityComboBox.SelectedItem, false);
            var useSourceSize = UseCaptureItemSizeCheckBox.IsChecked.Value;

            var temp    = MediaEncodingProfile.CreateMp4(quality);
            var bitrate = temp.Video.Bitrate;
            var width   = temp.Video.Width;
            var height  = temp.Video.Height;

            // Get our capture item
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item == null)
            {
                button.IsChecked = false;
                return;
            }

            // Use the capture item's size for the encoding if desired
            if (useSourceSize)
            {
                width  = (uint)item.Size.Width;
                height = (uint)item.Size.Height;

                // Even if we're using the capture item's real size,
                // we still want to make sure the numbers are even.
                // Some encoders get mad if you give them odd numbers.
                width  = EnsureEven(width);
                height = EnsureEven(height);
            }

            // Find a place to put our vidoe for now
            var file = await GetTempFileAsync();

            // Tell the user we've started recording
            MainTextBlock.Text = "● rec";
            var originalBrush = MainTextBlock.Foreground;

            MainTextBlock.Foreground        = new SolidColorBrush(Colors.Red);
            MainProgressBar.IsIndeterminate = true;


            //await StartCaptureAsync();

            // Kick off the encoding
            try
            {
                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                    using (_encoder = new Encoder(_device, item, _surface))
                    {
                        await _encoder.EncodeAsync(
                            stream,
                            width, height, bitrate,
                            frameRate);
                    }
                MainTextBlock.Foreground = originalBrush;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex);

                var message = GetMessageForHResult(ex.HResult);
                if (message == null)
                {
                    message = $"Uh-oh! Something went wrong!\n0x{ex.HResult:X8} - {ex.Message}";
                }
                var dialog = new MessageDialog(
                    message,
                    "Recording failed");

                await dialog.ShowAsync();

                button.IsChecked                = false;
                MainTextBlock.Text              = "failure";
                MainTextBlock.Foreground        = originalBrush;
                MainProgressBar.IsIndeterminate = false;
                return;
            }

            // At this point the encoding has finished,
            // tell the user we're now saving
            MainTextBlock.Text = "saving...";

            // Ask the user where they'd like the video to live
            var newFile = await PickVideoAsync();

            if (newFile == null)
            {
                // User decided they didn't want it
                // Throw out the encoded video
                button.IsChecked   = false;
                MainTextBlock.Text = "canceled";
                MainProgressBar.IsIndeterminate = false;
                await file.DeleteAsync();

                return;
            }
            // Move our vidoe to its new home
            await file.MoveAndReplaceAsync(newFile);

            // Tell the user we're done
            button.IsChecked   = false;
            MainTextBlock.Text = "done";
            MainProgressBar.IsIndeterminate = false;

            // Open the final product
            await Launcher.LaunchFileAsync(newFile);
        }
コード例 #27
0
 public VideoCapture()
 {
     this.picker = new GraphicsCapturePicker();
     this.device = Direct3D11Helper.CreateDevice();
 }
コード例 #28
0
        private async void ToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            var button = (ToggleButton)sender;

            // Get our encoder properties
            var frameRateItem  = (FrameRateItem)FrameRateComboBox.SelectedItem;
            var resolutionItem = (ResolutionItem)ResolutionComboBox.SelectedItem;
            var bitrateItem    = (BitrateItem)BitrateComboBox.SelectedItem;

            if (UseCaptureItemToggleSwitch.IsOn)
            {
                resolutionItem.IsZero();
            }

            var width     = resolutionItem.Resolution.Width;
            var height    = resolutionItem.Resolution.Height;
            var bitrate   = bitrateItem.Bitrate;
            var frameRate = frameRateItem.FrameRate;

            if (UseCaptureItemToggleSwitch.IsOn)
            {
                resolutionItem.IsZero();
            }

            // Get our capture item
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item == null)
            {
                button.IsChecked = false;
                return;
            }

            // Use the capture item's size for the encoding if desired
            if (UseCaptureItemToggleSwitch.IsOn)
            {
                width  = (uint)item.Size.Width;
                height = (uint)item.Size.Height;

                // Even if we're using the capture item's real size,
                // we still want to make sure the numbers are even.
                // Some encoders get mad if you give them odd numbers.
                width  = EnsureEven(width);
                height = EnsureEven(height);
            }

            // Put videos in the temp folder
            var tempFile = await GetTempFileAsync();

            _tempFile = tempFile;

            // Tell the user we've started recording

            var visual    = ElementCompositionPreview.GetElementVisual(Ellipse);
            var animation = visual.Compositor.CreateScalarKeyFrameAnimation();

            animation.InsertKeyFrame(0, 1);
            animation.InsertKeyFrame(1, 0);
            animation.Duration          = TimeSpan.FromMilliseconds(1500);
            animation.IterationBehavior = AnimationIterationBehavior.Forever;
            visual.StartAnimation("Opacity", animation);

            RecordIcon.Visibility = Visibility.Collapsed;
            StopIcon.Visibility   = Visibility.Visible;
            Ellipse.Visibility    = Visibility.Visible;
            ToolTip toolTip = new ToolTip();

            toolTip.Content = "Stop recording";
            ToolTipService.SetToolTip(MainButton, toolTip);
            AutomationProperties.SetName(MainButton, "Stop recording");
            MainTextBlock.Text = "recording...";
            var originalBrush = MainTextBlock.Foreground;

            MainTextBlock.Foreground = new SolidColorBrush(Colors.Red);

            // Kick off the encoding
            try
            {
                using (var stream = await tempFile.OpenAsync(FileAccessMode.ReadWrite))
                    using (_encoder = new Encoder(_device, item))
                    {
                        var encodesuccess = await _encoder.EncodeAsync(
                            stream,
                            width, height, bitrate,
                            frameRate);

                        if (encodesuccess == false)
                        {
                            ContentDialog errorDialog = new ContentDialog
                            {
                                Title           = "Recording failed",
                                Content         = "Windows cannot encode your video",
                                CloseButtonText = "OK"
                            };
                            await errorDialog.ShowAsync();
                        }
                    }
                MainTextBlock.Foreground = originalBrush;
            }
            catch (Exception ex)
            {
                Crashes.TrackError(ex);
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex);

                var message = GetMessageForHResult(ex.HResult);
                if (message == null)
                {
                    message = $"Whoops, something went wrong!\n0x{ex.HResult:X8} - {ex.Message}";
                }
                ContentDialog errorDialog = new ContentDialog
                {
                    Title           = "Recording failed",
                    Content         = message,
                    CloseButtonText = "OK"
                };
                await errorDialog.ShowAsync();

                button.IsChecked = false;
                visual.StopAnimation("Opacity");

                Ellipse.Visibility       = Visibility.Collapsed;
                MainTextBlock.Text       = "failure";
                MainTextBlock.Foreground = originalBrush;
                RecordIcon.Visibility    = Visibility.Visible;
                StopIcon.Visibility      = Visibility.Collapsed;
                toolTip.Content          = "Start recording";
                ToolTipService.SetToolTip(MainButton, toolTip);
                AutomationProperties.SetName(MainButton, "Start recording");
                await _tempFile.DeleteAsync();

                return;
            }

            // At this point the encoding has finished,
            // tell the user we're now saving

            MainButton.IsChecked = false;
            MainTextBlock.Text   = "";
            visual.StopAnimation("Opacity");
            Ellipse.Visibility    = Visibility.Collapsed;
            RecordIcon.Visibility = Visibility.Visible;
            StopIcon.Visibility   = Visibility.Collapsed;
            ToolTip newtoolTip = new ToolTip();

            toolTip.Content = "Start recording";
            ToolTipService.SetToolTip(MainButton, toolTip);
            AutomationProperties.SetName(MainButton, "Start recording");

            if (PreviewToggleSwitch.IsOn)
            {
                CoreApplicationView newView = CoreApplication.CreateNewView();
                int newViewId = 0;
                await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    var preview = new VideoPreviewPage(_tempFile);
                    ApplicationViewTitleBar formattableTitleBar = ApplicationView.GetForCurrentView().TitleBar;
                    formattableTitleBar.ButtonBackgroundColor   = Colors.Transparent;
                    CoreApplicationViewTitleBar coreTitleBar    = CoreApplication.GetCurrentView().TitleBar;
                    coreTitleBar.ExtendViewIntoTitleBar         = true;
                    Window.Current.Content = preview;
                    Window.Current.Activate();
                    newViewId = ApplicationView.GetForCurrentView().Id;
                });

                bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
            }
            else
            {
                ContentDialog dialog = new SaveDialog(_tempFile);
                await dialog.ShowAsync();
            }
        }
コード例 #29
0
        private async void MainToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            // Select what we want to capture
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                // Get a temporary file to save our gif to
                var file = await GetTempFileAsync();

                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                {
                    // Get the various d3d objects we'll need
                    var d3dDevice = Direct3D11Helpers.CreateSharpDXDevice(_device);

                    // Create our encoder
                    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.GifEncoderId, stream);

                    // Write the application block
                    // http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
                    var containerProperties = encoder.BitmapContainerProperties;
                    await containerProperties.SetPropertiesAsync(new[]
                    {
                        new KeyValuePair <string, BitmapTypedValue>("/appext/application", new BitmapTypedValue(PropertyValue.CreateUInt8Array(Encoding.ASCII.GetBytes("NETSCAPE2.0")), PropertyType.UInt8Array)),
                        // The first value is the size of the block, which is the fixed value 3.
                        // The second value is the looping extension, which is the fixed value 1.
                        // The third and fourth values comprise an unsigned 2-byte integer (little endian).
                        //     The value of 0 means to loop infinitely.
                        // The final value is the block terminator, which is the fixed value 0.
                        new KeyValuePair <string, BitmapTypedValue>("/appext/data", new BitmapTypedValue(PropertyValue.CreateUInt8Array(new byte[] { 3, 1, 0, 0, 0 }), PropertyType.UInt8Array)),
                    });

                    // Setup Windows.Graphics.Capture
                    var itemSize  = item.Size;
                    var framePool = Direct3D11CaptureFramePool.CreateFreeThreaded(
                        _device,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        1,
                        itemSize);
                    var session = framePool.CreateCaptureSession(item);

                    // We need a blank texture (background) and a texture that will hold the frame we'll be encoding
                    var description = new SharpDX.Direct3D11.Texture2DDescription
                    {
                        Width             = itemSize.Width,
                        Height            = itemSize.Height,
                        MipLevels         = 1,
                        ArraySize         = 1,
                        Format            = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                        SampleDescription = new SharpDX.DXGI.SampleDescription()
                        {
                            Count   = 1,
                            Quality = 0
                        },
                        Usage          = SharpDX.Direct3D11.ResourceUsage.Default,
                        BindFlags      = SharpDX.Direct3D11.BindFlags.ShaderResource | SharpDX.Direct3D11.BindFlags.RenderTarget,
                        CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
                        OptionFlags    = SharpDX.Direct3D11.ResourceOptionFlags.None
                    };
                    var gifTexture       = new SharpDX.Direct3D11.Texture2D(d3dDevice, description);
                    var renderTargetView = new SharpDX.Direct3D11.RenderTargetView(d3dDevice, gifTexture);

                    // Encode frames as they arrive. Because we created our frame pool using
                    // Direct3D11CaptureFramePool::CreateFreeThreaded, this lambda will fire on a different thread
                    // than our current one. If you'd like the callback to fire on your thread, create the frame pool
                    // using Direct3D11CaptureFramePool::Create and make sure your thread has a DispatcherQueue and you
                    // are pumping messages.
                    TimeSpan lastTimeStamp = TimeSpan.MinValue;
                    var      frameCount    = 0;
                    framePool.FrameArrived += async(s, a) =>
                    {
                        using (var frame = s.TryGetNextFrame())
                        {
                            var contentSize = frame.ContentSize;
                            var timeStamp   = frame.SystemRelativeTime;
                            using (var sourceTexture = Direct3D11Helpers.CreateSharpDXTexture2D(frame.Surface))
                            {
                                var width  = Math.Clamp(contentSize.Width, 0, itemSize.Width);
                                var height = Math.Clamp(contentSize.Height, 0, itemSize.Height);

                                var region = new SharpDX.Direct3D11.ResourceRegion(0, 0, 0, width, height, 1);

                                d3dDevice.ImmediateContext.ClearRenderTargetView(renderTargetView, new SharpDX.Mathematics.Interop.RawColor4(0, 0, 0, 1));
                                d3dDevice.ImmediateContext.CopySubresourceRegion(sourceTexture, 0, region, gifTexture, 0);
                            }

                            if (lastTimeStamp == TimeSpan.MinValue)
                            {
                                lastTimeStamp = timeStamp;
                            }
                            var timeStampDelta = timeStamp - lastTimeStamp;
                            lastTimeStamp = timeStamp;
                            var milliseconds = timeStampDelta.TotalMilliseconds;
                            // Use 10ms units
                            var frameDelay = milliseconds / 10;

                            if (frameCount > 0)
                            {
                                await encoder.GoToNextFrameAsync();
                            }

                            // Write our frame delay
                            await encoder.BitmapProperties.SetPropertiesAsync(new[]
                            {
                                new KeyValuePair <string, BitmapTypedValue>("/grctlext/Delay", new BitmapTypedValue(PropertyValue.CreateUInt16((ushort)frameDelay), PropertyType.UInt16)),
                            });

                            // Write the frame to our image
                            var gifSurface = Direct3D11Helpers.CreateDirect3DSurfaceFromSharpDXTexture(gifTexture);
                            var copy       = await SoftwareBitmap.CreateCopyFromSurfaceAsync(gifSurface);

                            encoder.SetSoftwareBitmap(copy);
                            frameCount++;
                        }
                    };

                    session.StartCapture();

                    await _semaphore.WaitAsync();

                    session.Dispose();
                    framePool.Dispose();
                    await Task.Delay(1000);

                    await encoder.FlushAsync();

                    var newFile = await PickGifAsync();

                    if (newFile == null)
                    {
                        await file.DeleteAsync();

                        return;
                    }
                    await file.MoveAndReplaceAsync(newFile);

                    await Launcher.LaunchFileAsync(newFile);
                }
            }
        }
コード例 #30
0
        private async void ScreenshotButton_Click(object sender, RoutedEventArgs e)
        {
            var filePicker = new FileSavePicker();

            filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            filePicker.SuggestedFileName      = "screenshot";
            filePicker.DefaultFileExtension   = ".png";
            filePicker.FileTypeChoices.Add("PNG Image", new string[] { ".png" });
            var file = await filePicker.PickSaveFileAsync();

            if (file != null)
            {
                var capturePicker = new GraphicsCapturePicker();
                var item          = await capturePicker.PickSingleItemAsync();

                if (item != null)
                {
                    var framePool = Direct3D11CaptureFramePool.CreateFreeThreaded(
                        _device,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        1,
                        item.Size);
                    var session = framePool.CreateCaptureSession(item);

                    var completionSource = new TaskCompletionSource <Direct3D11Texture2D>();
                    framePool.FrameArrived += (s, a) =>
                    {
                        using (var frame = s.TryGetNextFrame())
                        {
                            var frameTexture = Direct3D11Texture2D.CreateFromDirect3DSurface(frame.Surface);
                            var description  = frameTexture.Description2D;
                            description.Usage          = Direct3DUsage.Staging;
                            description.BindFlags      = 0;
                            description.CpuAccessFlags = Direct3D11CpuAccessFlag.AccessRead;
                            description.MiscFlags      = 0;
                            var copyTexture = _device.CreateTexture2D(description);

                            _deviceContext.CopyResource(copyTexture, frameTexture);

                            session.Dispose();
                            framePool.Dispose();

                            completionSource.SetResult(copyTexture);
                        }
                    };

                    session.StartCapture();
                    var texture = await completionSource.Task;
                    var bits    = texture.GetBytes();

                    using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                    {
                        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);

                        encoder.SetPixelData(
                            BitmapPixelFormat.Bgra8,
                            BitmapAlphaMode.Premultiplied,
                            (uint)item.Size.Width,
                            (uint)item.Size.Height,
                            1.0,
                            1.0,
                            bits);
                        await encoder.FlushAsync();
                    }

                    await Launcher.LaunchFileAsync(file);
                }
            }
        }