Skip to content

Commit

Permalink
重构 截图1/n
Browse files Browse the repository at this point in the history
  • Loading branch information
MakesYT committed May 16, 2024
1 parent d30b6df commit 8009698
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 77 deletions.
52 changes: 21 additions & 31 deletions Core/SDKs/HotKey/HotKeyManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,28 @@ public class HotKeyManager
private static Timer keyPressTimer = new(1000);
private static bool canPress = true;
public static SimpleReactiveGlobalHook hook;
public static event EventHandler<HotKeyModel> OnHotKeyPressed ;
public static event EventHandler<HotKeyModel> OnHotKeyPressed;

public static ObservableCollection<HotKeyModel> HotKeys
{
get;
set;
} = new();
public static ObservableCollection<HotKeyModel> HotKeys { get; set; } = new();

public static void Init()
{
OnHotKeyPressed += (sender, model) =>
{
log.Debug($"快捷键{model.MainName} {model.Name}被触发");
};
OnHotKeyPressed += (sender, model) => { log.Debug($"快捷键{model.MainName} {model.Name}被触发"); };
hook = new SimpleReactiveGlobalHook();
hook.KeyPressed.Subscribe(OnKeyPressed);
hook.KeyReleased.Subscribe(OnKeyReleased);
hook.MousePressed.Subscribe(OnMousePressed);
hook.MouseReleased.Subscribe(OnMouseReleased);
keyPressTimer.AutoReset = true;
keyPressTimer.Elapsed += (_timer, _) =>
{
canPress = true;
};
keyPressTimer.Elapsed += (_timer, _) => { canPress = true; };
hook.RunAsync();
foreach (var customScenario in CustomScenarioManger.CustomScenarios)
{
HotKeys.Add(customScenario.RunHotKey);
HotKeys.Add(customScenario.StopHotKey);
}
}


private static void OnKeyPressed(KeyboardHookEventArgs e)
{
Expand Down Expand Up @@ -98,8 +88,9 @@ private static void OnKeyPressed(KeyboardHookEventArgs e)
if ((int)configHotKey.SelectKey != (int)e.Data.KeyCode)
{
continue;
}
OnHotKeyPressed.Invoke( new(), configHotKey);
}

OnHotKeyPressed.Invoke(new(), configHotKey);

switch (configHotKey.MainName)
{
Expand All @@ -110,22 +101,22 @@ private static void OnKeyPressed(KeyboardHookEventArgs e)
case "截图":
{
log.Debug("截图热键被触发");
Dispatcher.UIThread.InvokeAsync(() =>
{
ServiceManager.Services.GetService<IScreenCapture>()!.CaptureScreen();
}).GetTask().ContinueWith((e) =>
{
if (e.IsFaulted)
{
log.Error(e.Exception);
ServiceManager.Services.GetService<IErrorWindow>()!.ShowErrorWindow("截图失败", e.Exception.Message);
}
});
Dispatcher.UIThread.InvokeAsync(() => {
ServiceManager.Services.GetService<IScreenCaptureWindow>()!.CaptureScreen();
})
.GetTask()
.ContinueWith((e) => {
if (e.IsFaulted)
{
log.Error(e.Exception);
ServiceManager.Services.GetService<IErrorWindow>()!.ShowErrorWindow(
"截图失败", e.Exception.Message);
}
});
break;
}
case "显示搜索框":
{

log.Debug("显示搜索框热键被触发");
ServiceManager.Services.GetService<ISearchWindowService>()!.ShowOrHiddenSearchWindow();

Expand Down Expand Up @@ -199,8 +190,7 @@ private static void OnMousePressed(MouseHookEventArgs e)

if (_timer is null)
{
_timer = new TimerHelper(ConfigManger.Config.mouseKeyInverval, () =>
{
_timer = new TimerHelper(ConfigManger.Config.mouseKeyInverval, () => {
log.Debug("快捷键触发");
ServiceManager.Services.GetService<IMouseQuickWindowService>()!.Open();
});
Expand Down
10 changes: 8 additions & 2 deletions Core/SDKs/Services/IScreenCapture.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
namespace Core.SDKs.Services;
using Avalonia.Media.Imaging;

namespace Core.SDKs.Services;

public interface IScreenCapture
{
public void CaptureScreen();
public (Queue<Bitmap>, Queue<Bitmap>) CaptureAllScreen();

public (Bitmap?, Bitmap?)? CaptureScreen(int index = 0, bool withMosaic = false);

public (Bitmap?, Bitmap?)? CaptureScreen(int index, int x, int y, int width, int height, bool withMosaic = false);
}
6 changes: 6 additions & 0 deletions Core/SDKs/Services/IScreenCaptureWindow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Core.SDKs.Services;

public interface IScreenCaptureWindow
{
public void CaptureScreen();
}
181 changes: 171 additions & 10 deletions Core/SDKs/Tools/ScreenCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,47 @@
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using ScreenCapture.NET;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Pbm;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Qoi;
using SixLabors.ImageSharp.Formats.Tga;
using SixLabors.ImageSharp.Formats.Tiff;
using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using IScreenCapture = Core.SDKs.Services.IScreenCapture;

namespace Core.SDKs.Tools;

public static class ScreenCapture
public class ScreenCapture : IScreenCapture
{
static Queue<Bitmap> bitmaps = new();
public static Queue<Bitmap> mosaics = new();
static SixLabors.ImageSharp.Configuration customConfig = SixLabors.ImageSharp.Configuration.Default.Clone();
private static readonly Lazy<Configuration> Lazy = new(CreateDefaultInstance);

public static Queue<Bitmap> CaptureAllScreen()
private static Configuration CreateDefaultInstance()
{
customConfig.PreferContiguousImageBuffers = true;
return new Configuration(
new PngConfigurationModule(),
new JpegConfigurationModule(),
new GifConfigurationModule(),
new BmpConfigurationModule(),
new PbmConfigurationModule(),
new TgaConfigurationModule(),
new TiffConfigurationModule(),
new WebpConfigurationModule(),
new QoiConfigurationModule())
{
PreferContiguousImageBuffers = true
};
}

public (Queue<Bitmap>, Queue<Bitmap>) CaptureAllScreen()
{
Queue<Bitmap> bitmaps = new();
Queue<Bitmap> mosaics = new();
using var screenCaptureService = new DX11ScreenCaptureService();
var graphicsCards = screenCaptureService.GetGraphicsCards();

Expand All @@ -27,13 +54,13 @@ public static Queue<Bitmap> CaptureAllScreen()
var captureZone = screenCapture.RegisterCaptureZone(0, 0, display.Width, display.Height);

while (!screenCapture.CaptureScreen()) ;
using var loadPixelData = SixLabors.ImageSharp.Image.LoadPixelData<Bgra32>(customConfig,
using var loadPixelData = Image.LoadPixelData<Bgra32>(Lazy.Value,
captureZone.RawBuffer,
captureZone.Width, captureZone.Height);
var clone = loadPixelData.Clone();
using (clone)
{
clone.Mutate( x => x.BoxBlur(10));
clone.Mutate(x => x.BoxBlur(10));
if (!clone.DangerousTryGetSinglePixelMemory(out Memory<Bgra32> memory1))
{
throw new Exception(
Expand All @@ -51,6 +78,7 @@ public static Queue<Bitmap> CaptureAllScreen()
}
}
}

if (!loadPixelData.DangerousTryGetSinglePixelMemory(out Memory<Bgra32> memory))
{
throw new Exception(
Expand All @@ -69,7 +97,140 @@ public static Queue<Bitmap> CaptureAllScreen()
}
}

return bitmaps;
return (bitmaps, mosaics);
}

public (Bitmap?, Bitmap?)? CaptureScreen(int index, bool withMosaic = false)
{
using var screenCaptureService = new DX11ScreenCaptureService();
var graphicsCards = screenCaptureService.GetGraphicsCards();

var enumerable = screenCaptureService.GetDisplays(graphicsCards.First());
if (index + 1 > enumerable.Count())
{
return (null, null);
}

var display = enumerable.ElementAtOrDefault(index);
using var screenCapture = screenCaptureService.GetScreenCapture(display);
var captureZone = screenCapture.RegisterCaptureZone(0, 0, display.Width, display.Height);

while (!screenCapture.CaptureScreen()) ;
using var loadPixelData = Image.LoadPixelData<Bgra32>(Lazy.Value,
captureZone.RawBuffer,
captureZone.Width, captureZone.Height);
Bitmap? mosaic = null;
if (withMosaic)
{
var clone = loadPixelData.Clone();
using (clone)
{
clone.Mutate(x => x.BoxBlur(10));
if (!clone.DangerousTryGetSinglePixelMemory(out Memory<Bgra32> memory1))
{
throw new Exception(
"This can only happen with multi-GB images or when PreferContiguousImageBuffers is not set to true.");
}

using (MemoryHandle pinHandle = memory1.Pin())
{
unsafe
{
var bitmap1 = new Bitmap(PixelFormat.Bgra8888, AlphaFormat.Unpremul, (IntPtr)pinHandle.Pointer,
new PixelSize(captureZone.Width, captureZone.Height), new Vector(96, 96),
(captureZone.Height * PixelFormat.Bgra8888.BitsPerPixel + 7) / 8);
mosaic = bitmap1;
}
}
}
}

if (!loadPixelData.DangerousTryGetSinglePixelMemory(out Memory<Bgra32> memory))
{
throw new Exception(
"This can only happen with multi-GB images or when PreferContiguousImageBuffers is not set to true.");
}

Bitmap? bitmap = null;
using (MemoryHandle pinHandle = memory.Pin())
{
unsafe
{
var bitmap1 = new Bitmap(PixelFormat.Bgra8888, AlphaFormat.Unpremul, (IntPtr)pinHandle.Pointer,
new PixelSize(captureZone.Width, captureZone.Height), new Vector(96, 96),
(captureZone.Height * PixelFormat.Bgra8888.BitsPerPixel + 7) / 8);
bitmap = bitmap1;
}
}


return (bitmap, mosaic);
}

public (Bitmap?, Bitmap?)? CaptureScreen(int index, int x, int y, int width, int height, bool withMosaic = false)
{
using var screenCaptureService = new DX11ScreenCaptureService();
var graphicsCards = screenCaptureService.GetGraphicsCards();

var enumerable = screenCaptureService.GetDisplays(graphicsCards.First());
if (index + 1 > enumerable.Count())
{
return (null, null);
}

var display = enumerable.ElementAtOrDefault(index);
using var screenCapture = screenCaptureService.GetScreenCapture(display);
var captureZone = screenCapture.RegisterCaptureZone(x, y, width, height);

while (!screenCapture.CaptureScreen()) ;
using var loadPixelData = Image.LoadPixelData<Bgra32>(Lazy.Value,
captureZone.RawBuffer,
captureZone.Width, captureZone.Height);
Bitmap? mosaic = null;
if (withMosaic)
{
var clone = loadPixelData.Clone();
using (clone)
{
clone.Mutate(x => x.BoxBlur(10));
if (!clone.DangerousTryGetSinglePixelMemory(out Memory<Bgra32> memory1))
{
throw new Exception(
"This can only happen with multi-GB images or when PreferContiguousImageBuffers is not set to true.");
}

using (MemoryHandle pinHandle = memory1.Pin())
{
unsafe
{
var bitmap1 = new Bitmap(PixelFormat.Bgra8888, AlphaFormat.Unpremul, (IntPtr)pinHandle.Pointer,
new PixelSize(captureZone.Width, captureZone.Height), new Vector(96, 96),
(captureZone.Height * PixelFormat.Bgra8888.BitsPerPixel + 7) / 8);
mosaic = bitmap1;
}
}
}
}

if (!loadPixelData.DangerousTryGetSinglePixelMemory(out Memory<Bgra32> memory))
{
throw new Exception(
"This can only happen with multi-GB images or when PreferContiguousImageBuffers is not set to true.");
}

Bitmap? bitmap = null;
using (MemoryHandle pinHandle = memory.Pin())
{
unsafe
{
var bitmap1 = new Bitmap(PixelFormat.Bgra8888, AlphaFormat.Unpremul, (IntPtr)pinHandle.Pointer,
new PixelSize(captureZone.Width, captureZone.Height), new Vector(96, 96),
(captureZone.Height * PixelFormat.Bgra8888.BitsPerPixel + 7) / 8);
bitmap = bitmap1;
}
}


return (bitmap, mosaic);
}

}
Loading

0 comments on commit 8009698

Please sign in to comment.