Extracted ScreenCapture-library from ambilight project

This commit is contained in:
DarthAffe committed 2021-04-11 00:05:51 +02:00
1 parent 8e58c0bc2b
commit c1dd816015
13 files changed
+791

No files matched your search

+119
View File
@@ -0,0 +1,119 @@
using System;
namespace ScreenCapture
{
public sealed class BlackBarDetection
{
#region Properties & Fields
private readonly CaptureZone _captureZone;
private int? _top;
public int Top => _top ??= CalculateTop();
private int? _bottom;
public int Bottom => _bottom ??= CalculateBottom();
private int? _left;
public int Left => _left ??= CalculateLeft();
private int? _right;
public int Right => _right ??= CalculateRight();
private int _theshold = 0;
public int Threshold
{
get => _theshold;
set
{
_theshold = value;
InvalidateCache();
}
}
#endregion
#region Constructors
public BlackBarDetection(CaptureZone captureZone)
{
this._captureZone = captureZone;
}
#endregion
#region Methods
public void InvalidateCache()
{
_top = null;
_bottom = null;
_left = null;
_right = null;
}
private int CalculateTop()
{
int threshold = Threshold;
int stride = _captureZone.BufferWidth * 4;
int bytesPerRow = _captureZone.Width * 4;
for (int row = 0; row < _captureZone.Height; row++)
{
Span<byte> data = new(_captureZone.Buffer, row * stride, bytesPerRow);
for (int i = 0; i < data.Length; i += 4)
if ((data[i] > threshold) || (data[i + 1] > threshold) || (data[i + 2] > threshold))
return row;
}
return 0;
}
private int CalculateBottom()
{
int threshold = Threshold;
int stride = _captureZone.BufferWidth * 4;
int bytesPerRow = _captureZone.Width * 4;
for (int row = _captureZone.Height; row >= 0; row--)
{
Span<byte> data = new(_captureZone.Buffer, row * stride, bytesPerRow);
for (int i = 0; i < data.Length; i += 4)
if ((data[i] > threshold) || (data[i + 1] > threshold) || (data[i + 2] > threshold))
return _captureZone.Height - row;
}
return 0;
}
private int CalculateLeft()
{
int threshold = Threshold;
int stride = _captureZone.BufferWidth * 4;
byte[] buffer = _captureZone.Buffer;
for (int column = 0; column < _captureZone.Width; column++)
for (int row = 0; row < _captureZone.Height; row++)
{
int offset = (stride * row) + (column * 4);
if ((buffer[offset] > threshold) || (buffer[offset + 1] > threshold) || (buffer[offset + 2] > threshold)) return column;
}
return 0;
}
private int CalculateRight()
{
int threshold = Threshold;
int stride = _captureZone.BufferWidth * 4;
byte[] buffer = _captureZone.Buffer;
for (int column = _captureZone.Width; column >= 0; column--)
for (int row = 0; row < _captureZone.Height; row++)
{
int offset = (stride * row) + (column * 4);
if ((buffer[offset] > threshold) || (buffer[offset + 1] > threshold) || (buffer[offset + 2] > threshold)) return _captureZone.Width - column;
}
return 0;
}
#endregion
}
}
+72
View File
@@ -0,0 +1,72 @@
namespace ScreenCapture
{
public sealed class CaptureZone
{
#region Properties & Fields
public int Id { get; }
public int X { get; }
public int Y { get; }
public int Width { get; }
public int Height { get; }
public int DownscaleLevel { get; }
public int UnscaledWidth { get; }
public int UnscaledHeight { get; }
public int CaptureWidth { get; }
public int CaptureHeight { get; }
public int BufferWidth { get; }
public int BufferHeight { get; }
public byte[] Buffer { get; }
public BlackBarDetection BlackBars { get; }
public bool AutoUpdate { get; set; } = true;
public bool IsUpdateRequested { get; private set; }
#endregion
#region Constructors
public CaptureZone(int id, int x, int y, int width, int height, int downscaleLevel, int unscaledWidth, int unscaledHeight, int captureWidth, int captureHeight, int bufferWidth, int bufferHeight, byte[] buffer)
{
this.Id = id;
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
this.UnscaledWidth = unscaledWidth;
this.UnscaledHeight = unscaledHeight;
this.DownscaleLevel = downscaleLevel;
this.CaptureWidth = captureWidth;
this.CaptureHeight = captureHeight;
this.BufferWidth = bufferWidth;
this.BufferHeight = bufferHeight;
this.Buffer = buffer;
BlackBars = new BlackBarDetection(this);
}
#endregion
#region Methods
public void RequestUpdate() => IsUpdateRequested = true;
public void SetUpdated()
{
IsUpdateRequested = false;
BlackBars.InvalidateCache();
}
public override int GetHashCode() => Id;
public bool Equals(CaptureZone other) => Id == other.Id;
public override bool Equals(object? obj) => obj is CaptureZone other && Equals(other);
#endregion
}
}
+38
View File
@@ -0,0 +1,38 @@
namespace ScreenCapture
{
public readonly struct Display
{
#region Properties & Fields
public int Index { get; }
public string DeviceName { get; }
public int Width { get; }
public int Height { get; }
public GraphicsCard GraphicsCard { get; }
#endregion
#region Constructors
public Display(int index, string deviceName, int width, int height, GraphicsCard graphicsCard)
{
this.Index = index;
this.DeviceName = deviceName;
this.Width = width;
this.Height = height;
this.GraphicsCard = graphicsCard;
}
#endregion
#region Methods
public bool Equals(Display other) => Index == other.Index;
public override bool Equals(object? obj) => obj is Display other && Equals(other);
public override int GetHashCode() => Index;
#endregion
}
}
+34
View File
@@ -0,0 +1,34 @@
namespace ScreenCapture
{
public readonly struct GraphicsCard
{
#region Properties & Fields
public int Index { get; }
public string Name { get; }
public int VendorId { get; }
public int DeviceId { get; }
#endregion
#region Constructors
public GraphicsCard(int index, string name, int vendorId, int deviceId)
{
this.Index = index;
this.Name = name;
this.VendorId = vendorId;
this.DeviceId = deviceId;
}
#endregion
#region Methods
public bool Equals(GraphicsCard other) => Index == other.Index;
public override bool Equals(object? obj) => obj is GraphicsCard other && Equals(other);
public override int GetHashCode() => Index;
#endregion
}
}