/// キャプチャした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; }
/// キャプチャした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; } }