diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index e10935e7c..aabba5714 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -48,8 +48,8 @@
True
-
-
+
NativeRect, optional, with the source area from the screen
+ /// NativeSize, optional, specifying the resulting size
+ public BitmapScreenCapture(NativeRect? sourceCaptureBounds = null, NativeSize? requestedSize = null)
+ {
+ SourceRect = sourceCaptureBounds ?? DisplayInfo.ScreenBounds;
+
+ // Check if a size was specified, if this differs we need to stretch / scale
+ if (requestedSize.HasValue && requestedSize.Value != SourceRect.Size)
+ {
+ DestinationSize = requestedSize.Value;
+ _useStretch = true;
+ }
+ else
+ {
+ DestinationSize = SourceRect.Size;
+ _useStretch = false;
+ }
+
+ // Get a Device Context for the desktop
+ _desktopDcHandle = SafeWindowDcHandle.FromDesktop();
+
+ // Create a Device Context which is compatible with the desktop Device Context
+ _safeCompatibleDcHandle = Gdi32Api.CreateCompatibleDC(_desktopDcHandle);
+ // Create BitmapInfoHeader, which is later used in the CreateDIBSection
+ var bitmapInfoHeader = BitmapInfoHeader.Create(DestinationSize.Width, DestinationSize.Height, 32);
+ // Create a DibSection, a device-independent bitmap (DIB)
+ _safeDibSectionHandle = Gdi32Api.CreateDIBSection(_desktopDcHandle, ref bitmapInfoHeader, DibColors.RgbColors, out var bits, IntPtr.Zero, 0);
+
+ // select the device-independent bitmap in the device context, storing the previous.
+ // This is needed, so every interaction with the DC will go into the DIB.
+ _safeSelectObjectHandle = _safeCompatibleDcHandle.SelectObject(_safeDibSectionHandle);
+
+ // Create a wrapper around the bitmap data
+ _bitmap = new UnmanagedBitmap(bits, DestinationSize.Width, DestinationSize.Height);
+ }
+
+ ///
+ /// Capture a frame from the screen
+ ///
+ public void CaptureFrame()
+ {
+ if (_useStretch)
+ {
+ // capture from source and blt over (make copy) to the DIB (via the DC)
+ // use stretching as the source and destination have different sizes
+ Gdi32Api.StretchBlt(
+ _safeCompatibleDcHandle, 0, 0, DestinationSize.Width, DestinationSize.Height, // Destination
+ _desktopDcHandle, SourceRect.X, SourceRect.Y, SourceRect.Width, SourceRect.Height, // source
+ RasterOperations.SourceCopy | RasterOperations.CaptureBlt);
+ }
+ else
+ {
+ // capture from source and blt over (make copy) to the DIB (via the DC)
+ Gdi32Api.BitBlt(
+ _safeCompatibleDcHandle, 0, 0, DestinationSize.Width, DestinationSize.Height, // Destination
+ _desktopDcHandle, SourceRect.X, SourceRect.Y, // Source
+ RasterOperations.SourceCopy | RasterOperations.CaptureBlt);
+ }
+
+ _hasFrame = true;
+ }
+
+ ///
+ /// Get the frame, captured with the previous CaptureFrame call
+ ///
+ /// IBitmapWithNativeSupport
+ public IBitmapWithNativeSupport CurrentFrameAsBitmap() => _hasFrame ? _bitmap : null;
+
+ ///
+ /// Dispose all DC, DIB, handles etc
+ ///
+ public void Dispose()
+ {
+ _safeSelectObjectHandle.Dispose();
+ _safeDibSectionHandle.Dispose();
+ _safeCompatibleDcHandle.Dispose();
+ _desktopDcHandle.Dispose();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Greenshot.Addons/Core/WindowCapture.cs b/src/Greenshot.Addons/Core/WindowCapture.cs
index f748b00ae..451c75219 100644
--- a/src/Greenshot.Addons/Core/WindowCapture.cs
+++ b/src/Greenshot.Addons/Core/WindowCapture.cs
@@ -346,8 +346,7 @@ namespace Greenshot.Addons.Core
}
// get a .NET image object for it
- // A suggestion for the "A generic error occurred in GDI+." E_FAIL/0�80004005 error is to re-try...
- var success = false;
+ // A suggestion for the "A generic error occurred in GDI+." E_FAIL/0x80004005 error is to re-try...
ExternalException exception = null;
for (var i = 0; i < 3; i++)
{
@@ -408,9 +407,6 @@ namespace Greenshot.Addons.Core
// TODO: Optimize?
return BitmapWrapper.FromBitmap(Image.FromHbitmap(safeDibSectionHandle.DangerousGetHandle()));
}
- // We got through the capture without exception
- success = true;
- break;
}
catch (ExternalException ee)
{
@@ -418,13 +414,10 @@ namespace Greenshot.Addons.Core
exception = ee;
}
}
- if (!success)
+ Log.Error().WriteLine(null, "Still couldn't create Bitmap!");
+ if (exception != null)
{
- Log.Error().WriteLine(null, "Still couldn't create Bitmap!");
- if (exception != null)
- {
- throw exception;
- }
+ throw exception;
}
}
}
diff --git a/src/Greenshot.Gfx/BitmapWrapper.cs b/src/Greenshot.Gfx/BitmapWrapper.cs
index 5d991a0a6..f3c11ad34 100644
--- a/src/Greenshot.Gfx/BitmapWrapper.cs
+++ b/src/Greenshot.Gfx/BitmapWrapper.cs
@@ -19,6 +19,8 @@
using System.Drawing;
using System.Drawing.Imaging;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
namespace Greenshot.Gfx
{
@@ -49,7 +51,7 @@ namespace Greenshot.Gfx
public int Width => _bitmap.Width;
///
- public PixelFormat PixelFormat => _bitmap.PixelFormat;
+ public System.Drawing.Imaging.PixelFormat PixelFormat => _bitmap.PixelFormat;
///
public float HorizontalResolution => _bitmap.HorizontalResolution;
@@ -60,6 +62,24 @@ namespace Greenshot.Gfx
///
public Bitmap NativeBitmap => _bitmap;
+ ///
+ public BitmapSource NativeBitmapSource
+ {
+ get
+ {
+ var bitmapData = _bitmap.LockBits(new Rectangle(0, 0, _bitmap.Width, _bitmap.Height), ImageLockMode.ReadOnly, _bitmap.PixelFormat);
+ try
+ {
+ return BitmapSource.Create(bitmapData.Width, bitmapData.Height, _bitmap.HorizontalResolution, _bitmap.VerticalResolution, PixelFormats.Bgr24, null, bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride);
+ }
+ finally
+ {
+ _bitmap.UnlockBits(bitmapData);
+ }
+ }
+ }
+
+ ///
public Size Size => new Size(Width, Height);
///
diff --git a/src/Greenshot.Gfx/FastBitmap/FastBitmapFactory.cs b/src/Greenshot.Gfx/FastBitmap/FastBitmapFactory.cs
index 76e1aef83..2db885623 100644
--- a/src/Greenshot.Gfx/FastBitmap/FastBitmapFactory.cs
+++ b/src/Greenshot.Gfx/FastBitmap/FastBitmapFactory.cs
@@ -87,8 +87,7 @@ namespace Greenshot.Gfx.FastBitmap
/// float for horizontal DPI
/// float for horizontal DPI
/// IFastBitmap
- public static IFastBitmap CreateEmpty(Size newSize, PixelFormat pixelFormat = PixelFormat.DontCare, Color? backgroundColor = null, float horizontalResolution = 96f,
- float verticalResolution = 96f)
+ public static IFastBitmap CreateEmpty(Size newSize, PixelFormat pixelFormat = PixelFormat.DontCare, Color? backgroundColor = null, float horizontalResolution = 96f, float verticalResolution = 96f)
{
var destination = BitmapFactory.CreateEmpty(newSize.Width, newSize.Height, pixelFormat, backgroundColor, horizontalResolution, verticalResolution);
var fastBitmap = Create(destination);
diff --git a/src/Greenshot.Gfx/IBitmap.cs b/src/Greenshot.Gfx/IBitmap.cs
index 78e11c4ac..0916cfa03 100644
--- a/src/Greenshot.Gfx/IBitmap.cs
+++ b/src/Greenshot.Gfx/IBitmap.cs
@@ -20,6 +20,7 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
+using System.Windows.Media.Imaging;
namespace Greenshot.Gfx
{
@@ -61,9 +62,15 @@ namespace Greenshot.Gfx
public interface IBitmapWithNativeSupport : IBitmap
{
///
- /// Underlying image, or an on demand rendered version with different attributes as the original
+ /// Retrieves a Bitmap which only can be used as long as the underlying implementation is not disposed.
+ /// Do not dispose this.
///
Bitmap NativeBitmap { get; }
+
+ ///
+ /// Retrieves a BitmapSource which only can be used as long as the underlying implementation is not disposed.
+ ///
+ BitmapSource NativeBitmapSource { get; }
///
/// Return the Size
diff --git a/src/Greenshot.Gfx/Quantizer/WuQuantizer.cs b/src/Greenshot.Gfx/Quantizer/WuQuantizer.cs
index 0aa9a1cfe..847905408 100644
--- a/src/Greenshot.Gfx/Quantizer/WuQuantizer.cs
+++ b/src/Greenshot.Gfx/Quantizer/WuQuantizer.cs
@@ -149,12 +149,17 @@ namespace Greenshot.Gfx.Quantizer
}
}
}
-
+ ///
public void Dispose()
{
Dispose(true);
}
+
+ ///
+ /// Dispose implementation
+ ///
+ /// bool
protected virtual void Dispose(bool disposing)
{
if (!disposing)
@@ -308,7 +313,7 @@ namespace Greenshot.Gfx.Quantizer
_tag = new byte[Maxvolume];
- // precalculates lookup tables
+ // pre-calculates lookup tables
for (var k = 0; k < allowedColorCount; ++k)
{
Mark(_cubes[k], k, _tag);
diff --git a/src/Greenshot.Gfx/SvgBitmap.cs b/src/Greenshot.Gfx/SvgBitmap.cs
index f9d9930ce..fab793b58 100644
--- a/src/Greenshot.Gfx/SvgBitmap.cs
+++ b/src/Greenshot.Gfx/SvgBitmap.cs
@@ -20,7 +20,11 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
using Svg;
+using Color = System.Drawing.Color;
+using PixelFormat = System.Drawing.Imaging.PixelFormat;
namespace Greenshot.Gfx
@@ -111,6 +115,24 @@ namespace Greenshot.Gfx
///
public Bitmap NativeBitmap => GenerateNativeBitmap();
+ ///
+ public BitmapSource NativeBitmapSource
+ {
+ get
+ {
+ GenerateNativeBitmap();
+ var bitmapData = _imageClone.LockBits(new Rectangle(0, 0, _imageClone.Width, _imageClone.Height), ImageLockMode.ReadOnly, _imageClone.PixelFormat);
+ try
+ {
+ return BitmapSource.Create(bitmapData.Width, bitmapData.Height, _imageClone.HorizontalResolution, _imageClone.VerticalResolution, PixelFormats.Bgr24, null, bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride);
+ }
+ finally
+ {
+ _imageClone.UnlockBits(bitmapData);
+ }
+ }
+ }
+
private Bitmap GenerateNativeBitmap()
{
if (_imageClone?.Height == Height && _imageClone?.Width == Width)
@@ -128,11 +150,6 @@ namespace Greenshot.Gfx
public Size Size => new Size(Width, Height);
- public void DisposeNativeBitmap(Bitmap nativeBitmap)
- {
- // do nothing, we need this
- }
-
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
diff --git a/src/Greenshot.Gfx/UnmanagedBitmap.cs b/src/Greenshot.Gfx/UnmanagedBitmap.cs
index 9b391044b..6a5e9df63 100644
--- a/src/Greenshot.Gfx/UnmanagedBitmap.cs
+++ b/src/Greenshot.Gfx/UnmanagedBitmap.cs
@@ -19,10 +19,12 @@
using System;
using System.Drawing;
-using System.Drawing.Imaging;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
using Greenshot.Gfx.Structs;
+using PixelFormat = System.Drawing.Imaging.PixelFormat;
namespace Greenshot.Gfx
{
@@ -34,8 +36,13 @@ namespace Greenshot.Gfx
{
private readonly float _horizontalPixelsPerInch;
private readonly float _verticalPixelsPerInch;
+ // Bytes per line
private readonly int _stride;
+ // IntPtr to a global handle with the bitmap data, this will be freed on dispose
private IntPtr _hGlobal;
+ // IntPtr to the bits of the bitmap, if using the constructor with the IntPtr this will not be freed
+ private readonly IntPtr _bits;
+ // Optionally created when the user calls NativeBitmap
private Bitmap _nativeBitmap;
///
@@ -64,10 +71,30 @@ namespace Greenshot.Gfx
Height = height;
_stride = bytesPerPixel * width;
var bytesAllocated = height * _stride;
- _hGlobal = Marshal.AllocHGlobal(bytesAllocated);
+ _bits = _hGlobal = Marshal.AllocHGlobal(bytesAllocated);
GC.AddMemoryPressure(bytesAllocated);
}
+
+ ///
+ /// The constructor for the UnmanagedBitmap with already initialized bits
+ ///
+ /// IntPtr to the bits, this will not be freed
+ /// int
+ /// int
+ /// float
+ /// float
+ public UnmanagedBitmap(IntPtr bits, int width, int height, float horizontalPixelsPerInch = 0.96f, float verticalPixelsPerInch = 0.96f)
+ {
+ _horizontalPixelsPerInch = horizontalPixelsPerInch;
+ _verticalPixelsPerInch = verticalPixelsPerInch;
+ var bytesPerPixel = Marshal.SizeOf();
+ Width = width;
+ Height = height;
+ _stride = bytesPerPixel * width;
+ _bits = bits;
+ }
+
///
/// This returns a span with a the pixels for the specified line
///
@@ -79,7 +106,7 @@ namespace Greenshot.Gfx
{
unsafe
{
- var pixelRowPointer = _hGlobal + (y * _stride);
+ var pixelRowPointer = _bits + (y * _stride);
return new Span(pixelRowPointer.ToPointer(), Width);
}
}
@@ -96,7 +123,7 @@ namespace Greenshot.Gfx
{
unsafe
{
- return new Span(_hGlobal.ToPointer(), Height * Width);
+ return new Span(_bits.ToPointer(), Height * Width);
}
}
}
@@ -126,6 +153,25 @@ namespace Greenshot.Gfx
return format;
}
}
+
+ public System.Windows.Media.PixelFormat WpfPixelFormat
+ {
+ get
+ {
+ TPixelLayout empty = default;
+ switch (empty)
+ {
+ case Bgr24 _:
+ return PixelFormats.Bgr24;
+ case Bgra32 _:
+ return PixelFormats.Bgra32;
+ case Bgr32 _:
+ return PixelFormats.Bgr32;
+ default:
+ throw new NotSupportedException("Unknown pixel format");
+ }
+ }
+ }
///
public float VerticalResolution => _verticalPixelsPerInch;
@@ -141,7 +187,19 @@ namespace Greenshot.Gfx
{
get
{
- return _nativeBitmap ??= new Bitmap(Width, Height, _stride, PixelFormat, _hGlobal);
+ return _nativeBitmap ??= new Bitmap(Width, Height, _stride, PixelFormat, _bits);
+ }
+ }
+
+ ///
+ /// Convert this to a real bitmap
+ ///
+ /// BitmapSource
+ public BitmapSource NativeBitmapSource
+ {
+ get
+ {
+ return BitmapSource.Create(Width, Height, HorizontalResolution, VerticalResolution, WpfPixelFormat, null, _bits, _stride * Height, _stride);
}
}
diff --git a/src/Greenshot.PerformanceTests/CapturePerformance.cs b/src/Greenshot.PerformanceTests/CapturePerformance.cs
index af5cf8bda..969067f3e 100644
--- a/src/Greenshot.PerformanceTests/CapturePerformance.cs
+++ b/src/Greenshot.PerformanceTests/CapturePerformance.cs
@@ -18,6 +18,7 @@
// along with this program. If not, see .
using System;
+using System.Drawing.Imaging;
using System.IO;
using BenchmarkDotNet.Attributes;
using Dapplo.Log;
@@ -32,7 +33,7 @@ namespace Greenshot.PerformanceTests
///
/// This defines the benchmarks which can be done
///
- [MinColumn, MaxColumn, MemoryDiagnoser]
+ [MinColumn, MaxColumn, MemoryDiagnoser, CoreJob, ClrJob]
public class CapturePerformance
{
private static readonly LogSource Log = new LogSource();
@@ -40,6 +41,8 @@ namespace Greenshot.PerformanceTests
private GdiScreenCapture _screenCapture;
// A ScreenCapture which captures the whole screen (multi-monitor) but with half the destination size, uses stretch-blt
private GdiScreenCapture _screenCaptureResized;
+ private BitmapScreenCapture _screenBitmapCapture;
+ private BitmapScreenCapture _screenBitmapCaptureResized;
private AviWriter _aviWriter;
private IAviVideoStream _aviVideoStream;
@@ -47,8 +50,10 @@ namespace Greenshot.PerformanceTests
public void Setup()
{
_screenCapture = new GdiScreenCapture(DisplayInfo.ScreenBounds);
+ _screenBitmapCapture = new BitmapScreenCapture();
var resizedSize = new NativeSize(DisplayInfo.ScreenBounds.Width / 2, DisplayInfo.ScreenBounds.Height / 2);
_screenCaptureResized = new GdiScreenCapture(DisplayInfo.ScreenBounds, resizedSize);
+ _screenBitmapCaptureResized = new BitmapScreenCapture(DisplayInfo.ScreenBounds, resizedSize);
var aviFile = Path.Combine(Path.GetTempPath(), @"test.avi");
Log.Info().WriteLine("Writing AVI to {0}", aviFile);
@@ -61,12 +66,13 @@ namespace Greenshot.PerformanceTests
EmitIndex1 = true
};
_aviVideoStream = _aviWriter.AddVideoStream(resizedSize.Width, resizedSize.Height, BitsPerPixel.Bpp24);
+
}
///
/// This benchmarks a screen capture which does a lot of additional work
///
- [Benchmark]
+ //[Benchmark]
public void Capture()
{
using (var capture = WindowCapture.CaptureScreen())
@@ -90,6 +96,15 @@ namespace Greenshot.PerformanceTests
{
_screenCapture.CaptureFrame();
}
+
+ ///
+ /// Capture the screen directly into a bitmap
+ ///
+ [Benchmark]
+ public void CaptureBitmap()
+ {
+ _screenBitmapCapture.CaptureFrame();
+ }
///
/// Capture the screen with buffered settings, but resized (smaller) destination
@@ -99,6 +114,17 @@ namespace Greenshot.PerformanceTests
{
_screenCaptureResized.CaptureFrame();
}
+
+
+ ///
+ /// Capture the screen with buffered settings, but resized (smaller) destination
+ ///
+ //[Benchmark]
+ public void CapturebitmapResized()
+ {
+ _screenBitmapCaptureResized.CaptureFrame();
+ }
+
///
/// Capture the screen with buffered settings, but resized (smaller) destination
@@ -115,6 +141,8 @@ namespace Greenshot.PerformanceTests
public void Cleanup()
{
_screenCapture.Dispose();
+ _screenBitmapCapture.Dispose();
+ _screenBitmapCaptureResized.Dispose();
_aviWriter.Close();
}
}
diff --git a/src/Greenshot.PerformanceTests/GfxPerformance.cs b/src/Greenshot.PerformanceTests/GfxPerformance.cs
index d732a7a07..8e66baa33 100644
--- a/src/Greenshot.PerformanceTests/GfxPerformance.cs
+++ b/src/Greenshot.PerformanceTests/GfxPerformance.cs
@@ -11,7 +11,7 @@ namespace Greenshot.PerformanceTests
///
/// This defines the benchmarks which can be done
///
- [MinColumn, MaxColumn, MemoryDiagnoser]
+ [MinColumn, MaxColumn, MemoryDiagnoser, CoreJob, ClrJob]
public class GfxPerformance
{
private UnmanagedBitmap _unmanagedTestBitmap;
diff --git a/src/Greenshot.PerformanceTests/GfxPerformanceShort.cs b/src/Greenshot.PerformanceTests/GfxPerformanceShort.cs
deleted file mode 100644
index e84dd7eb4..000000000
--- a/src/Greenshot.PerformanceTests/GfxPerformanceShort.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System.Drawing;
-using System.Drawing.Imaging;
-using BenchmarkDotNet.Attributes;
-using Greenshot.Gfx;
-
-namespace Greenshot.PerformanceTests
-{
- ///
- /// This defines the benchmarks which can be done
- ///
- [MinColumn, MaxColumn, MemoryDiagnoser]
- public class GfxPerformanceShort
- {
- [Benchmark]
- [Arguments(PixelFormat.Format24bppRgb)]
- [Arguments(PixelFormat.Format32bppRgb)]
- [Arguments(PixelFormat.Format32bppArgb)]
- public void Blur(PixelFormat pixelFormat)
- {
- using (var bitmap = BitmapFactory.CreateEmpty(400, 400, pixelFormat, Color.White))
- {
- using (var graphics = Graphics.FromImage(bitmap.NativeBitmap))
- using (var pen = new SolidBrush(Color.Blue))
- {
- graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
- }
- bitmap.ApplyBoxBlur(10);
- }
- }
- }
-}
diff --git a/src/Greenshot.PerformanceTests/Greenshot.PerformanceTests.csproj b/src/Greenshot.PerformanceTests/Greenshot.PerformanceTests.csproj
index 27934dcf2..893b072bc 100644
--- a/src/Greenshot.PerformanceTests/Greenshot.PerformanceTests.csproj
+++ b/src/Greenshot.PerformanceTests/Greenshot.PerformanceTests.csproj
@@ -64,9 +64,7 @@
-
-
2.6.3
runtime; build; native; contentfiles; analyzers
@@ -75,7 +73,6 @@
-
diff --git a/src/Greenshot.PerformanceTests/Program.cs b/src/Greenshot.PerformanceTests/Program.cs
index cc17d23d7..81a236aff 100644
--- a/src/Greenshot.PerformanceTests/Program.cs
+++ b/src/Greenshot.PerformanceTests/Program.cs
@@ -30,7 +30,8 @@ namespace Greenshot.PerformanceTests
// ReSharper disable once UnusedParameter.Local
private static void Main(string[] args)
{
- BenchmarkRunner.Run();
+ //BenchmarkRunner.Run();
+ BenchmarkRunner.Run();
Console.ReadLine();
}
}
diff --git a/src/Greenshot.Tests/CaptureTests.cs b/src/Greenshot.Tests/CaptureTests.cs
index 2f613dcb7..403fc2c30 100644
--- a/src/Greenshot.Tests/CaptureTests.cs
+++ b/src/Greenshot.Tests/CaptureTests.cs
@@ -17,6 +17,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@@ -128,5 +129,34 @@ namespace Greenshot.Tests
await outputStream.CopyToAsync(fileStream);
}
}
+
+
+ ///
+ /// Test if capturing works
+ ///
+ [Fact]
+ public void Test_BitmapCapture()
+ {
+ using (var screenBitmapCapture = new BitmapScreenCapture())
+ {
+ screenBitmapCapture.CaptureFrame();
+
+ Assert.NotNull(screenBitmapCapture.CurrentFrameAsBitmap());
+
+ var testFile1 = Path.Combine(Path.GetTempPath(), @"test-bitmap.png");
+ screenBitmapCapture.CurrentFrameAsBitmap().NativeBitmap.Save(testFile1, ImageFormat.Png);
+
+ var testFile2 = Path.Combine(Path.GetTempPath(), @"test-bitmapsource.png");
+ using (var fileStream = new FileStream(testFile2, FileMode.Create))
+ {
+ var encoder = new PngBitmapEncoder
+ {
+ Interlace = PngInterlaceOption.Off
+ };
+ encoder.Frames.Add(BitmapFrame.Create(screenBitmapCapture.CurrentFrameAsBitmap().NativeBitmapSource));
+ encoder.Save(fileStream);
+ }
+ }
+ }
}
}