/// キャプチャしたbyte[]をBitmapSource(Freezed)にして返す /// @param request スクリーンキャプチャ設定をまとめたリクエスト /// @return スクリーンキャプチャ結果が格納されたBitmapSource private BitmapSource CaptureByGetDIBits(ScreenCaptureRequest request) { if (request.ClippingWidth <= 0 || request.ClippingHeight <= 0) { // Debug.WriteLine("Invalid clipping size", "ScreenCaptureTimer.CaptureByGetDIBits"); return(null); } // GetDIBitsでbyte[]にデータを格納 int dpiX, dpiY; var result = request.ExecuteByGetDIBits(out dpiX, out dpiY); if (result == null) { return(null); } var bitmap = BitmapSource.Create(request.ClippingWidth, request.ClippingHeight, dpiX, dpiY, PixelFormats.Bgr32, null, result, request.Stride); result = null; /// @todo(me) あまり大きな画像をメモリにおいておきたくない。 /// とはいえ、TransformedBitmapはちょっと重過ぎる。 /// メモリよりもCPUリソースを残しておきたいのでこのままでいいかも。 //bitmap = this.Resize(bitmap); // スレッド越しにアクセスされるためFreeze bitmap.Freeze(); return(bitmap); }
/// 結果を取得 /// @param layoutElement 対象のレイアウト要素 /// @return 生成済みならBitmapSourceを。でなければNullを返す。 public BitmapSource GetBitmapSource(LayoutElement layoutElement) { if (!layoutElement.IsWindowValid) { return(null); } var request = new ScreenCaptureRequest(layoutElement); /// ディクショナリはスレッドセーフではない lock (this.sharedLock) { BitmapSource result; var success = this.cache.TryGetValue(request, out result); Debug.WriteLineIf(!success, "No request in cache", "ScreenCaptureTimer"); return(result); } }
/// キャプチャしたHBitmapをBitmapSource(Freezed)にして返す /// @param request スクリーンキャプチャ設定をまとめたリクエスト /// @return スクリーンキャプチャ結果が格納されたBitmapSource private BitmapSource Capture(ScreenCaptureRequest request) { if (request.ClippingWidth <= 0 || request.ClippingHeight <= 0) { // Debug.WriteLine("Invalid clipping size", "ScreenCaptureTimer.CaptureByGetDIBits"); return(null); } // HBitmapからBitmapSourceを作成 BitmapSource bitmap = null; using (var result = request.Execute()) { if (result == null) { return(bitmap); } // HBitmapからBitmapSourceに変換 bitmap = Imaging.CreateBitmapSourceFromHBitmap( result.Bitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); // Debug.WriteLine(string.Format("Captured: {0:D}x{1:D}", // bitmap.PixelWidth, bitmap.PixelHeight), // "ScreenCapture"); } // Alphaチャンネル情報を削除 bitmap = new FormatConvertedBitmap(bitmap, PixelFormats.Bgr32, null, 0.0); /// @todo(me) あまり大きな画像をメモリにおいておきたくない。 /// とはいえ、TransformedBitmapはちょっと重過ぎる。 /// メモリよりもCPUリソースを残しておきたいのでこのままでいいかも。 //bitmap = this.Resize(bitmap); // スレッド越しにアクセスされるためFreeze bitmap.Freeze(); return(bitmap); }
private VideoInputConfigBase RebuildInputSource_Capture(string id, SceneItemSourceCapture capture, bool isWindow, StreamerRebuildContext rebuildContext) { var ci = _sources.GetOrCreateCaptureItem(capture.Source, isWindow); if (ci?.Wrapped != null) { var request = new ScreenCaptureRequest { Id = $"{capture.Source.CaptureId}", Cursor = capture.CaptureCursor, InitialSize = ci.Wrapped.Size, Item = ci.Wrapped, DebugName = capture.Source.Name }; return(new VideoInputConfigFull(new InputSetup(Type: ScreenCaptureContext.Name, Input: ci.Prefix + capture.Source.CaptureId, ObjectInput: request))); } else { return(GetFailedInputSource(id, rebuildContext, InputIssueDesc.CaptureNotFound, $"Capture target '{capture.Source.Name}' not found")); } }