diff --git a/ScreenCapture.NET/DirectX/DX11ScreenCapture.cs b/ScreenCapture.NET/DirectX/DX11ScreenCapture.cs
index e7e39ff..77d0b2d 100644
--- a/ScreenCapture.NET/DirectX/DX11ScreenCapture.cs
+++ b/ScreenCapture.NET/DirectX/DX11ScreenCapture.cs
@@ -171,17 +171,17 @@ namespace ScreenCapture.NET
if (scalingTexture != null)
{
_context.CopySubresourceRegion(scalingTexture, 0, 0, 0, 0, _captureTexture, 0,
- new Box(captureZone.X, captureZone.Y, 0,
- captureZone.X + captureZone.UnscaledWidth,
- captureZone.Y + captureZone.UnscaledHeight, 1));
+ new Box(captureZone.X, captureZone.Y, 0,
+ captureZone.X + captureZone.UnscaledWidth,
+ captureZone.Y + captureZone.UnscaledHeight, 1));
_context.GenerateMips(scalingTextureView);
_context.CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, scalingTexture, captureZone.DownscaleLevel);
}
else
_context.CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, _captureTexture, 0,
- new Box(captureZone.X, captureZone.Y, 0,
- captureZone.X + captureZone.UnscaledWidth,
- captureZone.Y + captureZone.UnscaledHeight, 1));
+ new Box(captureZone.X, captureZone.Y, 0,
+ captureZone.X + captureZone.UnscaledWidth,
+ captureZone.Y + captureZone.UnscaledHeight, 1));
MappedSubresource mapSource = _context.Map(stagingTexture, 0, MapMode.Read, MapFlags.None);
IntPtr sourcePtr = mapSource.DataPointer;
@@ -203,21 +203,13 @@ namespace ScreenCapture.NET
///
public CaptureZone RegisterCaptureZone(int x, int y, int width, int height, int downscaleLevel = 0)
{
- CaptureZoneValidityCheck(x, y, width, height);
+ ValidateCaptureZoneAndThrow(x, y, width, height);
int unscaledWidth = width;
int unscaledHeight = height;
- if (downscaleLevel > 0)
- for (int i = 0; i < downscaleLevel; i++)
- {
- width /= 2;
- height /= 2;
- }
+ (width, height) = CalculateScaledSize(unscaledWidth, unscaledHeight, downscaleLevel);
- if (width < 1) width = 1;
- if (height < 1) height = 1;
-
- byte[] buffer = new byte[width * height * 4];
+ byte[] buffer = new byte[width * height * BPP];
CaptureZone captureZone = new(_indexCounter++, x, y, width, height, BPP, downscaleLevel, unscaledWidth, unscaledHeight, buffer);
lock (_captureZones)
@@ -246,21 +238,59 @@ namespace ScreenCapture.NET
}
///
- public void RepositionCaptureZone(CaptureZone captureZone, int x, int y)
+ public void UpdateCaptureZone(CaptureZone captureZone, int? x = null, int? y = null, int? width = null, int? height = null, int? downscaleLevel = null)
{
- CaptureZoneValidityCheck(x, y, captureZone.UnscaledWidth, captureZone.UnscaledHeight);
-
lock (_captureZones)
- {
if (!_captureZones.ContainsKey(captureZone))
- throw new ArgumentException("Non registered CaptureZone", nameof(captureZone));
- }
+ throw new ArgumentException("The capture zone is not registered to this ScreenCapture", nameof(captureZone));
- captureZone.X = x;
- captureZone.Y = y;
+ int newX = x ?? captureZone.X;
+ int newY = y ?? captureZone.Y;
+ int newUnscaledWidth = width ?? captureZone.UnscaledWidth;
+ int newUnscaledHeight = height ?? captureZone.UnscaledHeight;
+ int newDownscaleLevel = downscaleLevel ?? captureZone.DownscaleLevel;
+
+ ValidateCaptureZoneAndThrow(newX, newY, newUnscaledWidth, newUnscaledHeight);
+
+ captureZone.X = newX;
+ captureZone.Y = newY;
+
+ //TODO DarthAffe 01.05.2022: For now just reinitialize the zone in that case, but this could be optimized to only recreate the textures needed.
+ if ((width != null) || (height != null) || (downscaleLevel != null))
+ {
+ (int newWidth, int newHeight) = CalculateScaledSize(newUnscaledWidth, newUnscaledHeight, newDownscaleLevel);
+ lock (_captureZones)
+ {
+ UnregisterCaptureZone(captureZone);
+
+ captureZone.UnscaledWidth = newUnscaledWidth;
+ captureZone.UnscaledHeight = newUnscaledHeight;
+ captureZone.Width = newWidth;
+ captureZone.Height = newHeight;
+ captureZone.DownscaleLevel = newDownscaleLevel;
+ captureZone.Buffer = new byte[newWidth * newHeight * BPP];
+
+ InitializeCaptureZone(captureZone);
+ }
+ }
}
- private void CaptureZoneValidityCheck(int x, int y, int width, int height)
+ private (int width, int height) CalculateScaledSize(int width, int height, int downscaleLevel)
+ {
+ if (downscaleLevel > 0)
+ for (int i = 0; i < downscaleLevel; i++)
+ {
+ width /= 2;
+ height /= 2;
+ }
+
+ if (width < 1) width = 1;
+ if (height < 1) height = 1;
+
+ return (width, height);
+ }
+
+ private void ValidateCaptureZoneAndThrow(int x, int y, int width, int height)
{
if (_device == null) throw new ApplicationException("ScreenCapture isn't initialized.");
diff --git a/ScreenCapture.NET/IScreenCapture.cs b/ScreenCapture.NET/IScreenCapture.cs
index 7107c35..e2b47e9 100644
--- a/ScreenCapture.NET/IScreenCapture.cs
+++ b/ScreenCapture.NET/IScreenCapture.cs
@@ -27,7 +27,7 @@ namespace ScreenCapture.NET
/// Creates a new for this .
///
/// The x-location of the region to capture (must be >= 0 and < screen-width).
- /// The x-location of the region to capture (must be >= 0 and < screen-height).
+ /// The y-location of the region to capture (must be >= 0 and < screen-height).
/// The width of the region to capture (must be >= 0 and this + x must be <= screen-width).
/// The height of the region to capture (must be >= 0 and this + y must be <= screen-height).
/// The level of downscaling applied to the image of this region before copying to local memory. The calculation is (width and height)/2^downscaleLevel.
@@ -42,13 +42,18 @@ namespace ScreenCapture.NET
bool UnregisterCaptureZone(CaptureZone captureZone);
///
- /// Updates the position of the given .
+ /// Updates the the given .
///
+ ///
+ /// null-parameters are ignored and not changed.
+ ///
/// The previously registered .
- /// The new x-location of the region on the screen.
- /// The new y-location of the region on the screen
- /// true if the was successfully repositioned; otherwise, false.
- void RepositionCaptureZone(CaptureZone captureZone, int x, int y);
+ /// The new x-location of the region to capture (must be >= 0 and < screen-width).
+ /// The new y-location of the region to capture (must be >= 0 and < screen-height).
+ /// The width of the region to capture (must be >= 0 and this + x must be <= screen-width).
+ /// The new height of the region to capture (must be >= 0 and this + y must be <= screen-height).
+ /// The new level of downscaling applied to the image of this region before copying to local memory. The calculation is (width and height)/2^downscaleLevel.
+ void UpdateCaptureZone(CaptureZone captureZone, int? x = null, int? y = null, int? width = null, int? height = null, int? downscaleLevel = null);
///
/// Restarts the .
diff --git a/ScreenCapture.NET/Model/CaptureZone.cs b/ScreenCapture.NET/Model/CaptureZone.cs
index 83ff803..460a0a6 100644
--- a/ScreenCapture.NET/Model/CaptureZone.cs
+++ b/ScreenCapture.NET/Model/CaptureZone.cs
@@ -27,29 +27,29 @@ namespace ScreenCapture.NET
public int Y { get; internal set; }
///
- /// Gets the width of the region on the screen.
+ /// Gets the width of the captured region.
///
- public int Width { get; }
+ public int Width { get; internal set; }
///
- /// Gets the height of the region on the screen.
+ /// Gets the height of the captured region.
///
- public int Height { get; }
+ public int Height { get; internal set; }
///
/// 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; }
+ public int DownscaleLevel { get; internal set; }
///
/// Gets the original width of the region (this equals if is 0).
///
- public int UnscaledWidth { get; }
+ public int UnscaledWidth { get; internal set; }
///
/// Gets the original height of the region (this equals if is 0).
///
- public int UnscaledHeight { get; }
+ public int UnscaledHeight { get; internal set; }
///
/// Gets the amount of bytes per pixel in the image (most likely 3 [RGB] or 4 [ARGB]).
@@ -64,7 +64,7 @@ namespace ScreenCapture.NET
///
/// Gets the buffer containing the image data. Format depends on the specific capture but is most likely BGRA32.
///
- public byte[] Buffer { get; }
+ public byte[] Buffer { get; internal set; }
///
/// Gets the config for black-bar detection.