Changed RepositionCaptureZone to UpdateCaptureZone and handled all kinds of changes

This commit is contained in:
Darth Affe 2022-05-01 14:29:55 +02:00
parent 520c4a98fc
commit dee0c096a6
3 changed files with 75 additions and 40 deletions

View File

@ -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
/// <inheritdoc />
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
}
/// <inheritdoc />
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.");

View File

@ -27,7 +27,7 @@ namespace ScreenCapture.NET
/// Creates a new <see cref="CaptureScreen"/> for this <see cref="IScreenCapture"/>.
/// </summary>
/// <param name="x">The x-location of the region to capture (must be &gt;= 0 and &lt; screen-width).</param>
/// <param name="y">The x-location of the region to capture (must be &gt;= 0 and &lt; screen-height).</param>
/// <param name="y">The y-location of the region to capture (must be &gt;= 0 and &lt; screen-height).</param>
/// <param name="width">The width of the region to capture (must be &gt;= 0 and this + x must be &lt;= screen-width).</param>
/// <param name="height">The height of the region to capture (must be &gt;= 0 and this + y must be &lt;= screen-height).</param>
/// <param name="downscaleLevel">The level of downscaling applied to the image of this region before copying to local memory. The calculation is (width and height)/2^downscaleLevel.</param>
@ -42,13 +42,18 @@ namespace ScreenCapture.NET
bool UnregisterCaptureZone(CaptureZone captureZone);
/// <summary>
/// Updates the position of the given <see cref="CaptureScreen"/>.
/// Updates the the given <see cref="CaptureScreen"/>.
/// </summary>
/// <remarks>
/// <c>null</c>-parameters are ignored and not changed.
/// </remarks>
/// <param name="captureZone">The previously registered <see cref="CaptureScreen"/>.</param>
/// <param name="x">The new x-location of the region on the screen.</param>
/// <param name="y">The new y-location of the region on the screen</param>
/// <returns><c>true</c> if the <see cref="CaptureScreen"/> was successfully repositioned; otherwise, <c>false</c>.</returns>
void RepositionCaptureZone(CaptureZone captureZone, int x, int y);
/// <param name="x">The new x-location of the region to capture (must be &gt;= 0 and &lt; screen-width).</param>
/// <param name="y">The new y-location of the region to capture (must be &gt;= 0 and &lt; screen-height).</param>
/// <param name="width">The width of the region to capture (must be &gt;= 0 and this + x must be &lt;= screen-width).</param>
/// <param name="height">The new height of the region to capture (must be &gt;= 0 and this + y must be &lt;= screen-height).</param>
/// <param name="downscaleLevel">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.</param>
void UpdateCaptureZone(CaptureZone captureZone, int? x = null, int? y = null, int? width = null, int? height = null, int? downscaleLevel = null);
/// <summary>
/// Restarts the <see cref="IScreenCapture"/>.

View File

@ -27,29 +27,29 @@ namespace ScreenCapture.NET
public int Y { get; internal set; }
/// <summary>
/// Gets the width of the region on the screen.
/// Gets the width of the captured region.
/// </summary>
public int Width { get; }
public int Width { get; internal set; }
/// <summary>
/// Gets the height of the region on the screen.
/// Gets the height of the captured region.
/// </summary>
public int Height { get; }
public int Height { get; internal set; }
/// <summary>
/// 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.
/// </summary>
public int DownscaleLevel { get; }
public int DownscaleLevel { get; internal set; }
/// <summary>
/// Gets the original width of the region (this equals <see cref="Width"/> if <see cref="DownscaleLevel"/> is 0).
/// </summary>
public int UnscaledWidth { get; }
public int UnscaledWidth { get; internal set; }
/// <summary>
/// Gets the original height of the region (this equals <see cref="Height"/> if <see cref="DownscaleLevel"/> is 0).
/// </summary>
public int UnscaledHeight { get; }
public int UnscaledHeight { get; internal set; }
/// <summary>
/// Gets the amount of bytes per pixel in the image (most likely 3 [RGB] or 4 [ARGB]).
@ -64,7 +64,7 @@ namespace ScreenCapture.NET
/// <summary>
/// Gets the buffer containing the image data. Format depends on the specific capture but is most likely BGRA32.
/// </summary>
public byte[] Buffer { get; }
public byte[] Buffer { get; internal set; }
/// <summary>
/// Gets the config for black-bar detection.