diff --git a/src/Artemis.Core/Services/RgbService.cs b/src/Artemis.Core/Services/RgbService.cs index 28937a7c3..ed226a331 100644 --- a/src/Artemis.Core/Services/RgbService.cs +++ b/src/Artemis.Core/Services/RgbService.cs @@ -44,6 +44,7 @@ namespace Artemis.Core.Services Surface.Exception += SurfaceOnException; Surface.SurfaceLayoutChanged += SurfaceOnLayoutChanged; _targetFrameRateSetting.SettingChanged += TargetFrameRateSettingOnSettingChanged; + _renderScaleSetting.SettingChanged += RenderScaleSettingOnSettingChanged; _enabledDevices = new List(); _devices = new List(); _ledMap = new Dictionary(); @@ -196,6 +197,10 @@ namespace Artemis.Core.Services } } + private void RenderScaleSettingOnSettingChanged(object? sender, EventArgs e) + { + _texture?.Invalidate(); + } public void Dispose() { diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs index a4bf80753..3845a31a4 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs @@ -78,7 +78,7 @@ namespace Artemis.UI.Shared penBrush.Freeze(); // Create transparent pixels covering the entire LedRect so the image size matched the LedRect size - drawingContext.DrawRectangle(new SolidColorBrush(Colors.Transparent), null, LedRect); + drawingContext.DrawRectangle(new SolidColorBrush(Colors.Transparent), new Pen(new SolidColorBrush(Colors.Transparent), 1), LedRect); // Translate to the top-left of the LedRect drawingContext.PushTransform(new TranslateTransform(LedRect.X, LedRect.Y)); // Render the LED geometry diff --git a/src/Artemis.UI/Screens/Settings/Debug/Tabs/RenderDebugView.xaml b/src/Artemis.UI/Screens/Settings/Debug/Tabs/RenderDebugView.xaml index 20ad8f5ad..05f2c83da 100644 --- a/src/Artemis.UI/Screens/Settings/Debug/Tabs/RenderDebugView.xaml +++ b/src/Artemis.UI/Screens/Settings/Debug/Tabs/RenderDebugView.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Debug.Tabs" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:s="https://github.com/canton7/Stylet" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:RenderDebugViewModel}"> @@ -12,6 +13,7 @@ + In this window you can view the inner workings of Artemis. @@ -38,5 +40,9 @@ + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Debug/Tabs/RenderDebugViewModel.cs b/src/Artemis.UI/Screens/Settings/Debug/Tabs/RenderDebugViewModel.cs index b66263387..934ba89b9 100644 --- a/src/Artemis.UI/Screens/Settings/Debug/Tabs/RenderDebugViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Debug/Tabs/RenderDebugViewModel.cs @@ -1,9 +1,11 @@ using System; +using System.IO; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; using Artemis.Core; using Artemis.Core.Services; +using Ookii.Dialogs.Wpf; using SkiaSharp; using SkiaSharp.Views.WPF; using Stylet; @@ -17,6 +19,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs private ImageSource _currentFrame; private int _renderWidth; private int _renderHeight; + private string _frameTargetPath; public RenderDebugViewModel(ICoreService coreService) { @@ -48,6 +51,20 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs set => SetAndNotify(ref _renderHeight, value); } + public void SaveFrame() + { + VistaSaveFileDialog dialog = new VistaSaveFileDialog {Filter = "Portable network graphic (*.png)|*.png", Title = "Save render frame"}; + dialog.FileName = $"Artemis frame {DateTime.Now:yyyy-dd-M--HH-mm-ss}.png"; + bool? result = dialog.ShowDialog(); + if (result == true) + { + if (dialog.FileName.EndsWith(".png")) + _frameTargetPath = dialog.FileName; + else + _frameTargetPath = dialog.FileName + ".png"; + } + } + protected override void OnActivate() { _coreService.FrameRendered += CoreServiceOnFrameRendered; @@ -76,8 +93,22 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs CurrentFrame = e.Texture.Bitmap.ToWriteableBitmap(); return; } - + using SKImage skImage = SKImage.FromPixels(e.Texture.Bitmap.PeekPixels()); + + if (_frameTargetPath != null) + { + using (SKData data = skImage.Encode(SKEncodedImageFormat.Png, 100)) + { + using (FileStream stream = File.OpenWrite(_frameTargetPath)) + { + data.SaveTo(stream); + } + } + + _frameTargetPath = null; + } + SKImageInfo info = new(skImage.Width, skImage.Height); writable.Lock(); using (SKPixmap pixmap = new(info, writable.BackBuffer, writable.BackBufferStride))