diff --git a/ScreenCapture.NET.DX11/DX11ScreenCapture.cs b/ScreenCapture.NET.DX11/DX11ScreenCapture.cs index d64d8ee..618711d 100644 --- a/ScreenCapture.NET.DX11/DX11ScreenCapture.cs +++ b/ScreenCapture.NET.DX11/DX11ScreenCapture.cs @@ -68,7 +68,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture /// The used to create underlying objects. /// The to duplicate. /// Indicates if the DuplicateOutput1 interface should be used instead of the older DuplicateOutput. Currently there's no real use in setting this to true. - public DX11ScreenCapture(IDXGIFactory1 factory, Display display, bool useNewDuplicationAdapter = false) + internal DX11ScreenCapture(IDXGIFactory1 factory, Display display, bool useNewDuplicationAdapter = false) : base(display) { this._factory = factory; @@ -81,6 +81,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture #region Methods + /// protected override bool PerformScreenCapture() { bool result = false; @@ -133,6 +134,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture return result; } + /// protected override void PerformCaptureZoneUpdate(CaptureZone captureZone, in Span buffer) { if (_context == null) return; @@ -299,6 +301,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture } } + /// protected override void ValidateCaptureZoneAndThrow(int x, int y, int width, int height, int downscaleLevel) { if (_device == null) throw new ApplicationException("ScreenCapture isn't initialized."); @@ -429,10 +432,13 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture } } + /// protected override void Dispose(bool disposing) { base.Dispose(disposing); - DisposeDX(); + + lock (_captureLock) + DisposeDX(); } private void DisposeDX() diff --git a/ScreenCapture.NET.DX9/DX9ScreenCapture.cs b/ScreenCapture.NET.DX9/DX9ScreenCapture.cs index bf057b6..cb7aec6 100644 --- a/ScreenCapture.NET.DX9/DX9ScreenCapture.cs +++ b/ScreenCapture.NET.DX9/DX9ScreenCapture.cs @@ -9,8 +9,8 @@ using Vortice.Direct3D9; namespace ScreenCapture.NET; /// -/// Represents a ScreenCapture using DirectX 11 desktop duplicaton. -/// https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/desktop-dup-api +/// Represents a ScreenCapture using DirectX 9. +/// https://learn.microsoft.com/en-us/windows/win32/api/d3d9/nf-d3d9-idirect3ddevice9-getfrontbufferdata /// // ReSharper disable once InconsistentNaming public sealed class DX9ScreenCapture : AbstractScreenCapture @@ -32,8 +32,9 @@ public sealed class DX9ScreenCapture : AbstractScreenCapture /// /// Initializes a new instance of the class. /// + /// The D3D9 instance used. /// The to duplicate. - public DX9ScreenCapture(IDirect3D9 direct3D9, Display display) + internal DX9ScreenCapture(IDirect3D9 direct3D9, Display display) : base(display) { this._direct3D9 = direct3D9; @@ -45,6 +46,7 @@ public sealed class DX9ScreenCapture : AbstractScreenCapture #region Methods + /// protected override bool PerformScreenCapture() { bool result = false; @@ -89,6 +91,7 @@ public sealed class DX9ScreenCapture : AbstractScreenCapture return result; } + /// protected override void PerformCaptureZoneUpdate(CaptureZone captureZone, in Span buffer) { if (_buffer == null) return; @@ -195,10 +198,13 @@ public sealed class DX9ScreenCapture : AbstractScreenCapture } } + /// protected override void Dispose(bool disposing) { base.Dispose(disposing); - DisposeDX(); + + lock (_captureLock) + DisposeDX(); } private void DisposeDX() diff --git a/ScreenCapture.NET.DX9/Downscale/SamplerInfo.cs b/ScreenCapture.NET.DX9/Downscale/SamplerInfo.cs index 97081e3..1862de2 100644 --- a/ScreenCapture.NET.DX9/Downscale/SamplerInfo.cs +++ b/ScreenCapture.NET.DX9/Downscale/SamplerInfo.cs @@ -43,8 +43,12 @@ internal readonly ref struct SamplerInfo /// /// Initializes a new instance of the class. /// + /// The X-location of the region the data comes from. + /// The Y-location of the region the data comes from. /// The width of the region the data comes from. /// The height of region the data comes from. + /// The number of pixels in a row of data. + /// The number of {T} representing a single pixel. /// The data to sample. public SamplerInfo(int x, int y, int width, int height, int stride, int dataPerPixel, in ReadOnlySpan data) { diff --git a/ScreenCapture.NET.X11/Downscale/SamplerInfo.cs b/ScreenCapture.NET.X11/Downscale/SamplerInfo.cs index 97081e3..1862de2 100644 --- a/ScreenCapture.NET.X11/Downscale/SamplerInfo.cs +++ b/ScreenCapture.NET.X11/Downscale/SamplerInfo.cs @@ -43,8 +43,12 @@ internal readonly ref struct SamplerInfo /// /// Initializes a new instance of the class. /// + /// The X-location of the region the data comes from. + /// The Y-location of the region the data comes from. /// The width of the region the data comes from. /// The height of region the data comes from. + /// The number of pixels in a row of data. + /// The number of {T} representing a single pixel. /// The data to sample. public SamplerInfo(int x, int y, int width, int height, int stride, int dataPerPixel, in ReadOnlySpan data) { diff --git a/ScreenCapture.NET.X11/X11ScreenCapture.cs b/ScreenCapture.NET.X11/X11ScreenCapture.cs index cf13cef..c35339e 100644 --- a/ScreenCapture.NET.X11/X11ScreenCapture.cs +++ b/ScreenCapture.NET.X11/X11ScreenCapture.cs @@ -7,7 +7,7 @@ namespace ScreenCapture.NET; /// /// Represents a ScreenCapture using libX11. -/// https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/desktop-dup-api +/// https://x.org/releases/current/doc/libX11/libX11/libX11.html#XGetImage /// // ReSharper disable once InconsistentNaming public sealed class X11ScreenCapture : AbstractScreenCapture @@ -31,7 +31,7 @@ public sealed class X11ScreenCapture : AbstractScreenCapture /// Initializes a new instance of the class. /// /// The to duplicate. - public X11ScreenCapture(Display display) + internal X11ScreenCapture(Display display) : base(display) { Restart(); @@ -41,6 +41,7 @@ public sealed class X11ScreenCapture : AbstractScreenCapture #region Methods + /// protected override bool PerformScreenCapture() { lock (_captureLock) @@ -57,6 +58,7 @@ public sealed class X11ScreenCapture : AbstractScreenCapture } } + /// protected override void PerformCaptureZoneUpdate(CaptureZone captureZone, in Span buffer) { using IDisposable @lock = captureZone.Lock(); @@ -158,6 +160,7 @@ public sealed class X11ScreenCapture : AbstractScreenCapture } } + /// protected override void Dispose(bool disposing) { base.Dispose(disposing); diff --git a/ScreenCapture.NET.X11/X11ScreenCaptureService.cs b/ScreenCapture.NET.X11/X11ScreenCaptureService.cs index c54f5d3..2e39c27 100644 --- a/ScreenCapture.NET.X11/X11ScreenCaptureService.cs +++ b/ScreenCapture.NET.X11/X11ScreenCaptureService.cs @@ -75,6 +75,8 @@ public class X11ScreenCaptureService : IScreenCaptureService /// IScreenCapture IScreenCaptureService.GetScreenCapture(Display display) => GetScreenCapture(display); + + /// public X11ScreenCapture GetScreenCapture(Display display) { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); diff --git a/ScreenCapture.NET/Generic/AbstractScreenCapture.cs b/ScreenCapture.NET/Generic/AbstractScreenCapture.cs index f7551f1..297d7e6 100644 --- a/ScreenCapture.NET/Generic/AbstractScreenCapture.cs +++ b/ScreenCapture.NET/Generic/AbstractScreenCapture.cs @@ -4,6 +4,7 @@ using System.Linq; namespace ScreenCapture.NET; +/// public abstract class AbstractScreenCapture : IScreenCapture where TColor : struct, IColor { @@ -11,20 +12,29 @@ public abstract class AbstractScreenCapture : IScreenCapture private bool _isDisposed; + /// + /// Gets a list of registered on this ScreenCature. + /// protected HashSet> CaptureZones { get; } = new(); + /// public Display Display { get; } #endregion #region Events + /// public event EventHandler? Updated; #endregion #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The to duplicate. protected AbstractScreenCapture(Display display) { this.Display = display; @@ -36,6 +46,7 @@ public abstract class AbstractScreenCapture : IScreenCapture #region Methods + /// public virtual bool CaptureScreen() { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); @@ -67,10 +78,23 @@ public abstract class AbstractScreenCapture : IScreenCapture return result; } + /// + /// Performs the actual screen capture. + /// + /// true if the screen was captured sucessfully; otherwise, false. protected abstract bool PerformScreenCapture(); + /// + /// Performs an update of the given capture zone. + /// + /// The capture zone to update. + /// The buffer containing the current pixel-data of the capture zone. protected abstract void PerformCaptureZoneUpdate(CaptureZone captureZone, in Span buffer); + /// + /// Raises the -event. + /// + /// A bool indicating whether the update was successful or not. protected virtual void OnUpdated(bool result) { try @@ -80,7 +104,10 @@ public abstract class AbstractScreenCapture : IScreenCapture catch { /**/ } } + /// ICaptureZone IScreenCapture.RegisterCaptureZone(int x, int y, int width, int height, int downscaleLevel) => RegisterCaptureZone(x, y, width, height, downscaleLevel); + + /// public virtual CaptureZone RegisterCaptureZone(int x, int y, int width, int height, int downscaleLevel = 0) { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); @@ -100,6 +127,15 @@ public abstract class AbstractScreenCapture : IScreenCapture } } + /// + /// Validates the given values of a capture zone. + /// + /// The X-location of the zone. + /// The Y-location of the zone. + /// The width of the zone. + /// The height of the zone. + /// The downscale-level of the zone. + /// Throws if some of the provided data is not valid. protected virtual void ValidateCaptureZoneAndThrow(int x, int y, int width, int height, int downscaleLevel) { if (x < 0) throw new ArgumentException("x < 0"); @@ -110,6 +146,13 @@ public abstract class AbstractScreenCapture : IScreenCapture if ((y + height) > Display.Height) throw new ArgumentException("y + height > Display height"); } + /// + /// Calculates the actual size when downscaling is used. + /// + /// The original width. + /// The original height. + /// The level of downscaling to be used. + /// A tuple containing the scaled width, the scaled height and the downscale-level used. (This can be smaller then the one provided if the image is not big enough to scale down that often.) protected virtual (int width, int height, int downscaleLevel) CalculateScaledSize(int width, int height, int downscaleLevel) { if (downscaleLevel > 0) @@ -131,7 +174,10 @@ public abstract class AbstractScreenCapture : IScreenCapture return (width, height, downscaleLevel); } + /// bool IScreenCapture.UnregisterCaptureZone(ICaptureZone captureZone) => UnregisterCaptureZone(captureZone as CaptureZone ?? throw new ArgumentException("Invalid capture-zone.")); + + /// public virtual bool UnregisterCaptureZone(CaptureZone captureZone) { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); @@ -139,8 +185,11 @@ public abstract class AbstractScreenCapture : IScreenCapture return CaptureZones.Remove(captureZone); } + /// void IScreenCapture.UpdateCaptureZone(ICaptureZone captureZone, int? x, int? y, int? width, int? height, int? downscaleLevel) => UpdateCaptureZone(captureZone as CaptureZone ?? throw new ArgumentException("Invalid capture-zone."), x, y, width, height, downscaleLevel); + + /// public virtual void UpdateCaptureZone(CaptureZone captureZone, int? x = null, int? y = null, int? width = null, int? height = null, int? downscaleLevel = null) { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); @@ -169,6 +218,7 @@ public abstract class AbstractScreenCapture : IScreenCapture } } + /// public virtual void Restart() { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); @@ -190,6 +240,7 @@ public abstract class AbstractScreenCapture : IScreenCapture _isDisposed = true; } + /// protected virtual void Dispose(bool disposing) { } #endregion diff --git a/ScreenCapture.NET/Model/CaptureZone.cs b/ScreenCapture.NET/Model/CaptureZone.cs index 2a30767..fca089c 100644 --- a/ScreenCapture.NET/Model/CaptureZone.cs +++ b/ScreenCapture.NET/Model/CaptureZone.cs @@ -17,98 +17,89 @@ public sealed class CaptureZone : ICaptureZone private readonly object _lock = new(); + /// public Display Display { get; } + /// public ColorFormat ColorFormat { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => TColor.ColorFormat; } - /// - /// Gets the x-location of the region on the screen. - /// + /// public int X { get; internal set; } - /// - /// Gets the y-location of the region on the screen. - /// + /// public int Y { get; internal set; } - /// - /// Gets the width of the captured region. - /// + /// public int Width { get; private set; } - /// - /// Gets the height of the captured region. - /// + /// public int Height { get; private set; } + /// public int Stride { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Width * ColorFormat.BytesPerPixel; } - /// - /// Gets the level of downscaling applied to the image of this region before copying to local memory. The calculation is (width and height)/2^downscaleLevel. - /// + /// public int DownscaleLevel { get; private set; } - /// - /// Gets the original width of the region (this equals if is 0). - /// + /// public int UnscaledWidth { get; private set; } - /// - /// Gets the original height of the region (this equals if is 0). - /// + /// public int UnscaledHeight { get; private set; } internal byte[] InternalBuffer { get; set; } + /// public ReadOnlySpan RawBuffer { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => InternalBuffer; } + /// + /// Gets the pixel-data of this zone. + /// public ReadOnlySpan Pixels { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => MemoryMarshal.Cast(RawBuffer); } + /// + /// Gets a . Basically the same as but with better performance. + /// public RefImage Image { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new(Pixels, 0, 0, Width, Height, Width); } + /// IImage ICaptureZone.Image { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Image(InternalBuffer, 0, 0, Width, Height, Width); } - /// - /// Gets or sets if the should be automatically updated on every captured frame. - /// + /// public bool AutoUpdate { get; set; } = true; - /// - /// Gets if an update for the is requested on the next captured frame. - /// + /// public bool IsUpdateRequested { get; private set; } #endregion #region Events - /// - /// Occurs when the is updated. - /// + /// public event EventHandler? Updated; #endregion @@ -146,6 +137,7 @@ public sealed class CaptureZone : ICaptureZone #region Methods + /// public RefImage GetRefImage() where T : struct, IColor { @@ -154,16 +146,14 @@ public sealed class CaptureZone : ICaptureZone return new RefImage(MemoryMarshal.Cast(RawBuffer), 0, 0, Width, Height, Width); } + /// public IDisposable Lock() { Monitor.Enter(_lock); return new UnlockDisposable(_lock); } - /// - /// Requests to update this when the next frame is captured. - /// Only necessary if is set to false. - /// + /// public void RequestUpdate() => IsUpdateRequested = true; /// @@ -209,6 +199,7 @@ public sealed class CaptureZone : ICaptureZone #region Methods + /// public void Dispose() { if (_disposed) throw new ObjectDisposedException("The lock is already released"); diff --git a/ScreenCapture.NET/Model/Colors/ColorABGR.cs b/ScreenCapture.NET/Model/Colors/ColorABGR.cs index 511a80b..00cfa36 100644 --- a/ScreenCapture.NET/Model/Colors/ColorABGR.cs +++ b/ScreenCapture.NET/Model/Colors/ColorABGR.cs @@ -5,12 +5,16 @@ using System.Runtime.InteropServices; namespace ScreenCapture.NET; +/// +/// Represents a color in 32 bit ABGR-format. +/// [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] [StructLayout(LayoutKind.Sequential)] public readonly struct ColorABGR : IColor { #region Properties & Fields + /// public static ColorFormat ColorFormat => ColorFormat.ABGR; private readonly byte _a; @@ -19,16 +23,30 @@ public readonly struct ColorABGR : IColor private readonly byte _r; // ReSharper disable ConvertToAutoPropertyWhenPossible + /// public byte A => _a; + + /// public byte B => _b; + + /// public byte G => _g; + + /// public byte R => _r; // ReSharper restore ConvertToAutoPropertyWhenPossible #endregion #region Constructors - + + /// + /// Initializes a new instance of the class. + /// + /// The alpha-component of the color. + /// The blue-component of the color. + /// The green-component of the color. + /// The red-component of the color. public ColorABGR(byte a, byte b, byte g, byte r) { this._a = a; @@ -41,6 +59,7 @@ public readonly struct ColorABGR : IColor #region Methods + /// public override string ToString() => $"[A: {_a}, R: {_r}, G: {_g}, B: {_b}]"; #endregion diff --git a/ScreenCapture.NET/Model/Colors/ColorARGB.cs b/ScreenCapture.NET/Model/Colors/ColorARGB.cs index c00980f..2758be5 100644 --- a/ScreenCapture.NET/Model/Colors/ColorARGB.cs +++ b/ScreenCapture.NET/Model/Colors/ColorARGB.cs @@ -5,12 +5,16 @@ using System.Runtime.InteropServices; namespace ScreenCapture.NET; +/// +/// Represents a color in 32 bit ARGB-format. +/// [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] [StructLayout(LayoutKind.Sequential)] public readonly struct ColorARGB : IColor { #region Properties & Fields + /// public static ColorFormat ColorFormat => ColorFormat.ARGB; private readonly byte _a; @@ -19,9 +23,16 @@ public readonly struct ColorARGB : IColor private readonly byte _b; // ReSharper disable ConvertToAutoPropertyWhenPossible + /// public byte A => _a; + + /// public byte R => _r; + + /// public byte G => _g; + + /// public byte B => _b; // ReSharper restore ConvertToAutoPropertyWhenPossible @@ -29,6 +40,13 @@ public readonly struct ColorARGB : IColor #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The alpha-component of the color. + /// The red-component of the color. + /// The green-component of the color. + /// The blue-component of the color. public ColorARGB(byte a, byte r, byte g, byte b) { this._a = a; @@ -41,6 +59,7 @@ public readonly struct ColorARGB : IColor #region Methods + /// public override string ToString() => $"[A: {_a}, R: {_r}, G: {_g}, B: {_b}]"; #endregion diff --git a/ScreenCapture.NET/Model/Colors/ColorBGR.cs b/ScreenCapture.NET/Model/Colors/ColorBGR.cs index 829d3b3..e6f1a12 100644 --- a/ScreenCapture.NET/Model/Colors/ColorBGR.cs +++ b/ScreenCapture.NET/Model/Colors/ColorBGR.cs @@ -5,12 +5,16 @@ using System.Runtime.InteropServices; namespace ScreenCapture.NET; +/// +/// Represents a color in 24 bit BGR-format. +/// [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] [StructLayout(LayoutKind.Sequential)] public readonly struct ColorBGR : IColor { #region Properties & Fields + /// public static ColorFormat ColorFormat => ColorFormat.BGR; private readonly byte _b; @@ -18,9 +22,16 @@ public readonly struct ColorBGR : IColor private readonly byte _r; // ReSharper disable ConvertToAutoPropertyWhenPossible + /// public byte A => byte.MaxValue; + + /// public byte B => _b; + + /// public byte G => _g; + + /// public byte R => _r; // ReSharper restore ConvertToAutoPropertyWhenPossible @@ -28,6 +39,12 @@ public readonly struct ColorBGR : IColor #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The blue-component of the color. + /// The green-component of the color. + /// The red-component of the color. public ColorBGR(byte b, byte g, byte r) { this._b = b; @@ -39,6 +56,7 @@ public readonly struct ColorBGR : IColor #region Methods + /// public override string ToString() => $"[A: {A}, R: {_r}, G: {_g}, B: {_b}]"; #endregion diff --git a/ScreenCapture.NET/Model/Colors/ColorBGRA.cs b/ScreenCapture.NET/Model/Colors/ColorBGRA.cs index 4029709..1db7ea3 100644 --- a/ScreenCapture.NET/Model/Colors/ColorBGRA.cs +++ b/ScreenCapture.NET/Model/Colors/ColorBGRA.cs @@ -5,12 +5,16 @@ using System.Runtime.InteropServices; namespace ScreenCapture.NET; +/// +/// Represents a color in 32 bit BGRA-format. +/// [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] [StructLayout(LayoutKind.Sequential)] public readonly struct ColorBGRA : IColor { #region Properties & Fields + /// public static ColorFormat ColorFormat => ColorFormat.BGRA; private readonly byte _b; @@ -19,9 +23,16 @@ public readonly struct ColorBGRA : IColor private readonly byte _a; // ReSharper disable ConvertToAutoPropertyWhenPossible + /// public byte B => _b; + + /// public byte G => _g; + + /// public byte R => _r; + + /// public byte A => _a; // ReSharper restore ConvertToAutoPropertyWhenPossible @@ -29,6 +40,13 @@ public readonly struct ColorBGRA : IColor #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The blue-component of the color. + /// The green-component of the color. + /// The red-component of the color. + /// The alpha-component of the color. public ColorBGRA(byte b, byte g, byte r, byte a) { this._b = b; @@ -41,6 +59,7 @@ public readonly struct ColorBGRA : IColor #region Methods + /// public override string ToString() => $"[A: {_a}, R: {_r}, G: {_g}, B: {_b}]"; #endregion diff --git a/ScreenCapture.NET/Model/Colors/ColorFormat.cs b/ScreenCapture.NET/Model/Colors/ColorFormat.cs index ff3b03a..a9f08e6 100644 --- a/ScreenCapture.NET/Model/Colors/ColorFormat.cs +++ b/ScreenCapture.NET/Model/Colors/ColorFormat.cs @@ -1,5 +1,8 @@ namespace ScreenCapture.NET; +/// +/// Represents a color format. +/// public readonly struct ColorFormat { #region Instances @@ -15,7 +18,14 @@ public readonly struct ColorFormat #region Properties & Fields + /// + /// Gets the Id of the color-format. + /// public readonly int Id; + + /// + /// Gets the Bytes per pixel for this color-format. + /// public readonly int BytesPerPixel; #endregion diff --git a/ScreenCapture.NET/Model/Colors/ColorRGB.cs b/ScreenCapture.NET/Model/Colors/ColorRGB.cs index ec4acc6..36dd932 100644 --- a/ScreenCapture.NET/Model/Colors/ColorRGB.cs +++ b/ScreenCapture.NET/Model/Colors/ColorRGB.cs @@ -5,12 +5,16 @@ using System.Runtime.InteropServices; namespace ScreenCapture.NET; +/// +/// Represents a color in 24 bit RGB-format. +/// [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] [StructLayout(LayoutKind.Sequential)] public readonly struct ColorRGB : IColor { #region Properties & Fields + /// public static ColorFormat ColorFormat => ColorFormat.RGB; private readonly byte _r; @@ -18,9 +22,16 @@ public readonly struct ColorRGB : IColor private readonly byte _b; // ReSharper disable ConvertToAutoPropertyWhenPossible + /// public byte A => byte.MaxValue; + + /// public byte R => _r; + + /// public byte G => _g; + + /// public byte B => _b; // ReSharper restore ConvertToAutoPropertyWhenPossible @@ -28,6 +39,12 @@ public readonly struct ColorRGB : IColor #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The red-component of the color. + /// The green-component of the color. + /// The blue-component of the color. public ColorRGB(byte r, byte g, byte b) { this._r = r; @@ -39,6 +56,7 @@ public readonly struct ColorRGB : IColor #region Methods + /// public override string ToString() => $"[A: {A}, R: {_r}, G: {_g}, B: {_b}]"; #endregion diff --git a/ScreenCapture.NET/Model/Colors/ColorRGBA.cs b/ScreenCapture.NET/Model/Colors/ColorRGBA.cs index 0b01e87..d51a7a1 100644 --- a/ScreenCapture.NET/Model/Colors/ColorRGBA.cs +++ b/ScreenCapture.NET/Model/Colors/ColorRGBA.cs @@ -5,12 +5,16 @@ using System.Runtime.InteropServices; namespace ScreenCapture.NET; +/// +/// Represents a color in 32 bit RGBA-format. +/// [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] [StructLayout(LayoutKind.Sequential)] public readonly struct ColorRGBA : IColor { #region Properties & Fields + /// public static ColorFormat ColorFormat => ColorFormat.RGBA; private readonly byte _r; @@ -19,9 +23,16 @@ public readonly struct ColorRGBA : IColor private readonly byte _a; // ReSharper disable ConvertToAutoPropertyWhenPossible + /// public byte R => _r; + + /// public byte G => _g; + + /// public byte B => _b; + + /// public byte A => _a; // ReSharper restore ConvertToAutoPropertyWhenPossible @@ -29,6 +40,13 @@ public readonly struct ColorRGBA : IColor #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The red-component of the color. + /// The green-component of the color. + /// The blue-component of the color. + /// The alpha-component of the color. public ColorRGBA(byte r, byte g, byte b, byte a) { this._r = r; @@ -41,6 +59,7 @@ public readonly struct ColorRGBA : IColor #region Methods + /// public override string ToString() => $"[A: {_a}, R: {_r}, G: {_g}, B: {_b}]"; #endregion diff --git a/ScreenCapture.NET/Model/Colors/IColor.cs b/ScreenCapture.NET/Model/Colors/IColor.cs index f3ea888..826c8db 100644 --- a/ScreenCapture.NET/Model/Colors/IColor.cs +++ b/ScreenCapture.NET/Model/Colors/IColor.cs @@ -2,12 +2,33 @@ namespace ScreenCapture.NET; +/// +/// Represents a generic color made of 4 bytes (alpha, red, green and blue) +/// public interface IColor { + /// + /// Gets the red-component of this color. + /// byte R { get; } + + /// + /// Gets the green-component of this color. + /// byte G { get; } + + /// + /// Gets the blue-component of this color. + /// byte B { get; } + + /// + /// Gets the alpha-component of this color. + /// byte A { get; } + /// + /// Gets the color-format of this color. + /// public static virtual ColorFormat ColorFormat => throw new NotSupportedException(); } \ No newline at end of file diff --git a/ScreenCapture.NET/Model/ICaptureZone.cs b/ScreenCapture.NET/Model/ICaptureZone.cs index 0379ee6..915da3a 100644 --- a/ScreenCapture.NET/Model/ICaptureZone.cs +++ b/ScreenCapture.NET/Model/ICaptureZone.cs @@ -2,61 +2,102 @@ namespace ScreenCapture.NET; +/// +/// Represents a zone on the screen to be captured. +/// public interface ICaptureZone { + /// + /// Gets the display this zone is on. + /// Display Display { get; } + + /// + /// Gets the color-format used in the buffer of this zone. + /// + ColorFormat ColorFormat { get; } + /// /// Gets the x-location of the region on the screen. /// int X { get; } + /// /// Gets the y-location of the region on the screen. /// int Y { get; } + /// /// Gets the width of the captured region. /// int Width { get; } + /// /// Gets the height of the captured region. /// int Height { get; } + + /// + /// Gets the stride of the buffer. + /// + int Stride { get; } + /// /// Gets the level of downscaling applied to the image of this region before copying to local memory. The calculation is (width and height)/2^downscaleLevel. /// int DownscaleLevel { get; } + /// /// Gets the original width of the region (this equals if is 0). /// int UnscaledWidth { get; } + /// /// Gets the original height of the region (this equals if is 0). /// int UnscaledHeight { get; } + /// + /// Gets the raw buffer of this zone. + /// ReadOnlySpan RawBuffer { get; } + /// + /// Gets the represented by the buffer of this zone. + /// IImage Image { get; } /// /// Gets or sets if the should be automatically updated on every captured frame. /// bool AutoUpdate { get; set; } + /// /// Gets if an update for the is requested on the next captured frame. /// bool IsUpdateRequested { get; } + /// /// Occurs when the is updated. /// event EventHandler? Updated; + /// + /// Locks the image for use. Unlock by disposing the returned disposable. + /// + /// The disposable used to unlock the image. + IDisposable Lock(); + /// /// Requests to update this when the next frame is captured. /// Only necessary if is set to false. /// void RequestUpdate(); - RefImage GetRefImage() - where TColor : struct, IColor; + /// + /// Gets a . Basically the same as but with better performance if the color-layout is known. + /// + /// The color used by the buffer of this zone. + /// The representing this zone. + RefImage GetRefImage() where TColor : struct, IColor; } diff --git a/ScreenCapture.NET/Model/IImage.cs b/ScreenCapture.NET/Model/IImage.cs index 3037521..a406a1f 100644 --- a/ScreenCapture.NET/Model/IImage.cs +++ b/ScreenCapture.NET/Model/IImage.cs @@ -2,38 +2,118 @@ namespace ScreenCapture.NET; +/// +/// Represents a image. +/// public interface IImage : IEnumerable { + /// + /// Gets the width of this image. + /// int Width { get; } + + /// + /// Gets the height of this image. + /// int Height { get; } + /// + /// Gets the color at the specified location. + /// + /// The X-location to read. + /// The Y-location to read. + /// The color at the specified location. IColor this[int x, int y] { get; } + + /// + /// Gets an image representing the specified location. + /// + /// The X-location of the image. + /// The Y-location of the image. + /// The width of the sub-image. + /// + /// IImage this[int x, int y, int width, int height] { get; } + /// + /// Gets a list of all rows of this image. + /// IImageRows Rows { get; } + + /// + /// Gets a list of all columns of this image. + /// IImageColumns Columns { get; } + /// + /// Represents a list of rows of an image. + /// public interface IImageRows : IEnumerable { + /// + /// Gets the amount of rows in this list. + /// int Count { get; } + + /// + /// Gets a specific . + /// + /// The ´row to get. + /// The requested . IImageRow this[int column] { get; } } + /// + /// Represents a list of columns of an image. + /// public interface IImageColumns : IEnumerable { + /// + /// Gets the amount of columns in this list. + /// int Count { get; } + + /// + /// Gets a specific . + /// + /// The column to get. + /// The requested . IImageColumn this[int column] { get; } } + /// + /// Represents a single row of an image. + /// public interface IImageRow : IEnumerable { + /// + /// Gets the length of the row. + /// int Length { get; } + + /// + /// Gets the at the specified location. + /// + /// The location to get the color from. + /// The at the specified location. IColor this[int x] { get; } } + /// + /// Represents a single column of an image. + /// public interface IImageColumn : IEnumerable { + /// + /// Gets the length of the column. + /// int Length { get; } + + /// + /// Gets the at the specified location. + /// + /// The location to get the color from. + /// The at the specified location. IColor this[int y] { get; } } } \ No newline at end of file diff --git a/ScreenCapture.NET/Model/Image.cs b/ScreenCapture.NET/Model/Image.cs index 295287a..bb3c1d2 100644 --- a/ScreenCapture.NET/Model/Image.cs +++ b/ScreenCapture.NET/Model/Image.cs @@ -6,6 +6,7 @@ using System.Runtime.InteropServices; namespace ScreenCapture.NET; +/// public sealed class Image : IImage where TColor : struct, IColor { @@ -17,13 +18,17 @@ public sealed class Image : IImage private readonly int _y; private readonly int _stride; + /// public int Width { get; } + + /// public int Height { get; } #endregion #region Indexer + /// public IColor this[int x, int y] { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -35,6 +40,7 @@ public sealed class Image : IImage } } + /// public IImage this[int x, int y, int width, int height] { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -46,12 +52,14 @@ public sealed class Image : IImage } } + /// public IImage.IImageRows Rows { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new ImageRows(_buffer, _x, _y, Width, Height, _stride); } + /// public IImage.IImageColumns Columns { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -76,6 +84,7 @@ public sealed class Image : IImage #region Methods + /// public IEnumerator GetEnumerator() { for (int y = 0; y < Height; y++) @@ -83,12 +92,14 @@ public sealed class Image : IImage yield return this[x, y]; } + /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion #region Indexer-Classes + /// private sealed class ImageRows : IImage.IImageRows { #region Properties & Fields @@ -100,12 +111,14 @@ public sealed class Image : IImage private readonly int _height; private readonly int _stride; + /// public int Count => _height; #endregion #region Indexer + /// public IImage.IImageRow this[int row] { get @@ -134,17 +147,20 @@ public sealed class Image : IImage #region Methods + /// public IEnumerator GetEnumerator() { for (int y = 0; y < _height; y++) yield return this[y]; } + /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion } + /// private sealed class ImageRow : IImage.IImageRow { #region Properties & Fields @@ -153,12 +169,14 @@ public sealed class Image : IImage private readonly int _start; private readonly int _length; + /// public int Length => _length; #endregion #region Indexer + /// public IColor this[int x] { get @@ -185,17 +203,20 @@ public sealed class Image : IImage #region Methods + /// public IEnumerator GetEnumerator() { for (int x = 0; x < _length; x++) yield return this[x]; } + /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion } + /// private sealed class ImageColumns : IImage.IImageColumns { #region Properties & Fields @@ -207,12 +228,14 @@ public sealed class Image : IImage private readonly int _height; private readonly int _stride; + /// public int Count => _width; #endregion #region Indexer + /// public IImage.IImageColumn this[int column] { get @@ -241,17 +264,20 @@ public sealed class Image : IImage #region Methods + /// public IEnumerator GetEnumerator() { for (int y = 0; y < _height; y++) yield return this[y]; } + /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion } + /// private sealed class ImageColumn : IImage.IImageColumn { #region Properties & Fields @@ -261,12 +287,14 @@ public sealed class Image : IImage private readonly int _length; private readonly int _step; + /// public int Length => _length; #endregion #region Indexer + /// public IColor this[int y] { get @@ -294,12 +322,14 @@ public sealed class Image : IImage #region Methods + /// public IEnumerator GetEnumerator() { for (int y = 0; y < _length; y++) yield return this[y]; } + /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion