Skip to content

Commit

Permalink
Make ScreenCapture generic TPixel;
Browse files Browse the repository at this point in the history
  • Loading branch information
Neakita committed Oct 12, 2024
1 parent 025078c commit 6ada416
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 50 deletions.
2 changes: 1 addition & 1 deletion SightKeeper.Application.Linux/X11/X11ScreenCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace SightKeeper.Application.Linux.X11;

public sealed class X11ScreenCapture : ScreenCapture, IDisposable
public sealed class X11ScreenCapture : ScreenCapture<Bgra32>, IDisposable
{
public X11ScreenCapture()
{
Expand Down
2 changes: 1 addition & 1 deletion SightKeeper.Application.Windows/DX11ScreenCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace SightKeeper.Application.Windows;

public sealed class DX11ScreenCapture : ScreenCapture, IDisposable
public sealed class DX11ScreenCapture : ScreenCapture<Bgra32>, IDisposable
{
public DX11ScreenCapture()
{
Expand Down
2 changes: 1 addition & 1 deletion SightKeeper.Application.Windows/WindowsScreenCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace SightKeeper.Application.Windows;

public sealed class WindowsScreenCapture : ScreenCapture
public sealed class WindowsScreenCapture : ScreenCapture<Bgra32>
{
public unsafe ReadOnlySpan2D<Bgra32> Capture(Vector2<ushort> resolution, Vector2<ushort> offset)
{
Expand Down
5 changes: 2 additions & 3 deletions SightKeeper.Application/ScreenCapture.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using CommunityToolkit.HighPerformance;
using SightKeeper.Domain.Model;
using SixLabors.ImageSharp.PixelFormats;

namespace SightKeeper.Application;

public interface ScreenCapture
public interface ScreenCapture<TPixel>
{
ReadOnlySpan2D<Bgra32> Capture(Vector2<ushort> resolution, Vector2<ushort> offset);
ReadOnlySpan2D<TPixel> Capture(Vector2<ushort> resolution, Vector2<ushort> offset);
}
8 changes: 4 additions & 4 deletions SightKeeper.Application/ScreenshotsDataAccess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,29 @@ public abstract class ScreenshotsDataAccess : ObservableDataAccess<Screenshot>,

public Screenshot CreateScreenshot(
ScreenshotsLibrary library,
Image imageData,
Image image,
DateTimeOffset creationDate,
Vector2<ushort> resolution)
{
var screenshot = library.CreateScreenshot(creationDate, resolution, out var removedScreenshots);
foreach (var removedScreenshot in removedScreenshots)
DeleteScreenshotData(removedScreenshot);
SaveScreenshotData(screenshot, imageData);
SaveScreenshotData(screenshot, image);
_added.OnNext(screenshot);
return screenshot;
}

public Screenshot<TAsset> CreateScreenshot<TAsset>(
ScreenshotsLibrary<TAsset> library,
Image imageData,
Image image,
DateTimeOffset creationDate,
Vector2<ushort> resolution)
where TAsset : Asset
{
var screenshot = library.CreateScreenshot(creationDate, resolution, out var removedScreenshots);
foreach (var removedScreenshot in removedScreenshots)
DeleteScreenshotData(removedScreenshot);
SaveScreenshotData(screenshot, imageData);
SaveScreenshotData(screenshot, image);
_added.OnNext(screenshot);
return screenshot;
}
Expand Down
49 changes: 9 additions & 40 deletions SightKeeper.Application/Screenshotter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CommunityToolkit.Diagnostics;
using CommunityToolkit.HighPerformance;
using HotKeys;
using HotKeys.ActionRunners;
using HotKeys.Bindings;
Expand All @@ -8,13 +7,10 @@
using SharpHook.Native;
using SightKeeper.Domain.Model;
using SightKeeper.Domain.Model.DataSets.Screenshots;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;

namespace SightKeeper.Application;

public sealed class Screenshotter
public abstract class Screenshotter
{
public bool IsEnabled
{
Expand Down Expand Up @@ -63,25 +59,25 @@ public Vector2<ushort> Resolution

public Gesture Gesture { get; set; } = new([new FormattedSharpButton(MouseButton.Button1)]);

public Screenshotter(
ScreenCapture screenCapture,
protected ScreenshotsDataAccess ScreenshotsDataAccess { get; }
protected TimeSpan Timeout => TimeSpan.FromSeconds(1) / FPS;
protected Vector2<ushort> Offset => _screenBoundsProvider.MainScreenCenter - _resolution / 2;

protected Screenshotter(
ScreenshotsDataAccess screenshotsDataAccess,
ScreenBoundsProvider screenBoundsProvider,
BindingsManager bindingsManager)
{
_screenCapture = screenCapture;
_screenshotsDataAccess = screenshotsDataAccess;
ScreenshotsDataAccess = screenshotsDataAccess;
_screenBoundsProvider = screenBoundsProvider;
_bindingsManager = bindingsManager;
}

protected abstract void MakeScreenshots(ActionContext context);

private const ushort MinimumResolutionDimension = 32;
private readonly ScreenCapture _screenCapture;
private readonly ScreenshotsDataAccess _screenshotsDataAccess;
private readonly ScreenBoundsProvider _screenBoundsProvider;
private readonly BindingsManager _bindingsManager;
private TimeSpan Timeout => TimeSpan.FromSeconds(1) / FPS;
private Vector2<ushort> Offset => _screenBoundsProvider.MainScreenCenter - _resolution / 2;
private float _fps = 10;
private Vector2<ushort> _resolution = new(320, 320);
private bool _isEnabled;
Expand All @@ -101,31 +97,4 @@ private void Disable()
_binding.Dispose();
_binding = null;
}

private void MakeScreenshots(ActionContext context)
{
var contextEliminated = false;
while (!contextEliminated && IsEnabled)
{
Guard.IsNotNull(Library);
var imageData = _screenCapture.Capture(Resolution, Offset);
using var image = LoadImage(imageData);
_screenshotsDataAccess.CreateScreenshot(Library, image, DateTimeOffset.Now, Resolution);
contextEliminated = context.WaitForElimination(Timeout);
}
}

private static Image<Bgra32> LoadImage(ReadOnlySpan2D<Bgra32> imageData)
{
if (imageData.TryGetSpan(out var span))
return Image.LoadPixelData(span, imageData.Width, imageData.Height);
Image<Bgra32> image = new(imageData.Width, imageData.Height);
for (int i = 0; i < imageData.Height; i++)
{
var source = imageData.GetRowSpan(i);
var target = image.DangerousGetPixelRowMemory(i);
source.CopyTo(target.Span);
}
return image;
}
}
52 changes: 52 additions & 0 deletions SightKeeper.Application/Screenshotter`1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using CommunityToolkit.Diagnostics;
using CommunityToolkit.HighPerformance;
using HotKeys.ActionRunners;
using HotKeys.Bindings;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;

namespace SightKeeper.Application;

public sealed class Screenshotter<TPixel> : Screenshotter
where TPixel : unmanaged, IPixel<TPixel>
{
public Screenshotter(
ScreenCapture<TPixel> screenCapture,
ScreenshotsDataAccess screenshotsDataAccess,
ScreenBoundsProvider screenBoundsProvider,
BindingsManager bindingsManager)
: base(screenshotsDataAccess, screenBoundsProvider, bindingsManager)
{
_screenCapture = screenCapture;
}

private readonly ScreenCapture<TPixel> _screenCapture;

protected override void MakeScreenshots(ActionContext context)
{
var contextEliminated = false;
while (!contextEliminated && IsEnabled)
{
Guard.IsNotNull(Library);
var imageData = _screenCapture.Capture(Resolution, Offset);
using var image = LoadImage(imageData);
ScreenshotsDataAccess.CreateScreenshot(Library, image, DateTimeOffset.Now, Resolution);
contextEliminated = context.WaitForElimination(Timeout);
}
}

private static Image<TPixel> LoadImage(ReadOnlySpan2D<TPixel> imageData)
{
if (imageData.TryGetSpan(out var span))
return Image.LoadPixelData(span, imageData.Width, imageData.Height);
Image<TPixel> image = new(imageData.Width, imageData.Height);
for (int i = 0; i < imageData.Height; i++)
{
var source = imageData.GetRowSpan(i);
var target = image.DangerousGetPixelRowMemory(i);
source.CopyTo(target.Span);
}
return image;
}
}

0 comments on commit 6ada416

Please sign in to comment.