From bb861834fd72618a55ac12a37cbeccd7c8b92f2d Mon Sep 17 00:00:00 2001 From: EugeneTes Date: Wed, 1 Apr 2026 14:05:37 +0200 Subject: [PATCH] settings for avalonia libcamera bugfix --- ...ettings.cs => LibcameraCaptureSettings.cs} | 4 +- .../LibcameraImageSource.cs | 112 +++--- VisionBuilder.UI.Avalonia.Uno/App.axaml.cs | 6 +- VisionBuilder.UI.Avalonia.Uno/Program.cs | 6 + .../Views/MainWindow.axaml | 10 + .../Views/MainWindow.axaml.cs | 21 +- .../VisionBuilder.UI.Avalonia.Uno.csproj | 1 + .../Services/AvaloniaSettingsService.cs | 31 +- .../VisionBuilder.UI.Avalonia.csproj | 1 + VisionBuilder.UI.Blazor.Uno/Program.cs | 1 + VisionBuilder.UI.Camera/ModuleExtensions.cs | 3 +- VisionBuilder.UI.Windows.Duo/Program.cs | 1 + VisionBuilder.UI.Windows.Test/Program.cs | 1 + VisionBuilder.UI.sln | 15 + .../Configuration/DefaultControlFactory.cs | 320 ++++++++++++++++++ .../Configuration/IControlFactory.cs | 11 + .../Configuration/ItemEditorDialog.axaml | 29 ++ .../Configuration/ItemEditorDialog.axaml.cs | 129 +++++++ .../Configuration/ListEditorDialog.axaml | 40 +++ .../Configuration/ListEditorDialog.axaml.cs | 165 +++++++++ .../Configuration/OptionSetting.cs | 12 + .../Configuration/OptionsWindow.axaml | 44 +++ .../Configuration/OptionsWindow.axaml.cs | 166 +++++++++ .../Configuration/SimplePropertyInfo.cs | 34 ++ .../Inspectron.Settings.Avalonia.csproj | 17 + .../PropHelper.cs | 18 + 26 files changed, 1139 insertions(+), 59 deletions(-) rename Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/{CaptureSettings.cs => LibcameraCaptureSettings.cs} (93%) create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/DefaultControlFactory.cs create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/IControlFactory.cs create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/ItemEditorDialog.axaml create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/ItemEditorDialog.axaml.cs create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/ListEditorDialog.axaml create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/ListEditorDialog.axaml.cs create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/OptionSetting.cs create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/OptionsWindow.axaml create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/OptionsWindow.axaml.cs create mode 100644 framework/Inspectron.Settings.Avalonia/Configuration/SimplePropertyInfo.cs create mode 100644 framework/Inspectron.Settings.Avalonia/Inspectron.Settings.Avalonia.csproj create mode 100644 framework/Inspectron.Settings.Avalonia/PropHelper.cs diff --git a/Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/CaptureSettings.cs b/Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/LibcameraCaptureSettings.cs similarity index 93% rename from Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/CaptureSettings.cs rename to Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/LibcameraCaptureSettings.cs index 01be2d0..db702e3 100644 --- a/Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/CaptureSettings.cs +++ b/Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/LibcameraCaptureSettings.cs @@ -3,11 +3,11 @@ using VisionBuilder.UI.Common; namespace Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera; -public class CaptureSettings : ISettings +public class LibcameraCaptureSettings : ISettings { public string CameraName { get; } - public CaptureSettings(string cameraName) + public LibcameraCaptureSettings(string cameraName) { CameraName = cameraName; } diff --git a/Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/LibcameraImageSource.cs b/Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/LibcameraImageSource.cs index f1df722..06c8950 100644 --- a/Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/LibcameraImageSource.cs +++ b/Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera/LibcameraImageSource.cs @@ -8,9 +8,9 @@ namespace Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera { public class LibcameraImageSource : IImageSource, IVisionBuilderModule { - private CaptureSettings _settings; + private LibcameraCaptureSettings _settings; - public LibcameraImageSource(CaptureSettings settings) + public LibcameraImageSource(LibcameraCaptureSettings settings) { _settings = settings; } @@ -41,72 +41,80 @@ namespace Hawkeye.VisionBuilder.UI.Sources.Raspberry.Libcamera private void StartLoop() { - var psi = new ProcessStartInfo + try { - FileName = "rpicam-vid", - Arguments = _settings.BuildArguments(), - RedirectStandardOutput = true, - UseShellExecute = false - }; + var psi = new ProcessStartInfo + { + FileName = "rpicam-vid", + Arguments = _settings.BuildArguments(), + RedirectStandardOutput = true, + UseShellExecute = false + }; - using (Process process = Process.Start(psi)) - using (BinaryReader br = new BinaryReader(process.StandardOutput.BaseStream)) - { - - byte[] imageBuffer = new byte[1024 * 1024]; - - - // decode MJPEG buffer - var buff = br.ReadBytes(ChunkSize); - int frameId = 0; - while (true) + using (Process process = Process.Start(psi)) + using (BinaryReader br = new BinaryReader(process.StandardOutput.BaseStream)) { + byte[] imageBuffer = new byte[1024 * 1024]; - var imageStart = Find(buff, JpegHeader); - if (imageStart != -1) + + // decode MJPEG buffer + var buff = br.ReadBytes(ChunkSize); + int frameId = 0; + while (true) { - var size = buff.Length - imageStart; - Array.Copy(buff, imageStart, imageBuffer, 0, size); - while (true) + + var imageStart = Find(buff, JpegHeader); + if (imageStart != -1) { - buff = br.ReadBytes(ChunkSize); - var imageEnd = Find(buff, JpegFooter); - if (imageEnd != -1) + var size = buff.Length - imageStart; + + Array.Copy(buff, imageStart, imageBuffer, 0, size); + while (true) { - var frame = new byte[size + imageEnd]; - Array.Copy(imageBuffer, frame, size); - Array.Copy(buff, 0, frame, size, imageEnd); - // process frame - frameId++; - var decoded = Mat.ImDecode(frame); + buff = br.ReadBytes(ChunkSize); + var imageEnd = Find(buff, JpegFooter); + if (imageEnd != -1) + { + var frame = new byte[size + imageEnd]; + Array.Copy(imageBuffer, frame, size); + Array.Copy(buff, 0, frame, size, imageEnd); + // process frame + frameId++; + var decoded = Mat.ImDecode(frame); - _imageChannel.Writer.WriteAsync(decoded, CancellationToken.None); + _imageChannel.Writer.WriteAsync(decoded, CancellationToken.None); - // copy the leftover data to the start - Array.Copy(buff, imageEnd, buff, 0, buff.Length - imageEnd); - // fill the remainder of the buffer with new data and start over - var temp = br.ReadBytes(imageEnd); - Array.Copy(temp, 0, buff, buff.Length - imageEnd, temp.Length); - break; + // copy the leftover data to the start + Array.Copy(buff, imageEnd, buff, 0, buff.Length - imageEnd); + // fill the remainder of the buffer with new data and start over + var temp = br.ReadBytes(imageEnd); + Array.Copy(temp, 0, buff, buff.Length - imageEnd, temp.Length); + break; + } + + // copy all of the data to the imageBuffer + Array.Copy(buff, 0, imageBuffer, size, buff.Length); + size += buff.Length; } - // copy all of the data to the imageBuffer - Array.Copy(buff, 0, imageBuffer, size, buff.Length); - size += buff.Length; } + else + { + Console.WriteLine("JPEG header not found."); + break; + } + } - else - { - Console.WriteLine("JPEG header not found."); - break; - } + + + process.Kill(); } - - - process.Kill(); - + } + catch (Exception e) + { + Serilog.Log.Error($"Error starting libcamera: {e}"); } } diff --git a/VisionBuilder.UI.Avalonia.Uno/App.axaml.cs b/VisionBuilder.UI.Avalonia.Uno/App.axaml.cs index 4448855..bacd890 100644 --- a/VisionBuilder.UI.Avalonia.Uno/App.axaml.cs +++ b/VisionBuilder.UI.Avalonia.Uno/App.axaml.cs @@ -7,6 +7,7 @@ using Ninject.Extensions.ChildKernel; using VisionBuilder.UI.Common; using VisionBuilder.UI.Common.Plugins; using VisionBuilder.UI.Common.Processing; +using VisionBuilder.UI.Common.Services; using VisionBuilder.UI.Common.ViewModel; using VisionBuilder.UI.IOCommander; using VisionBuilder.UI.Recipes.HawkeyeRecipe; @@ -15,6 +16,7 @@ using VisionBuilder.UI.Statistics; using VisionBuilder.UI.Avalonia; using VisionBuilder.UI.Avalonia.Uno.Views; using Lindt.Colorballs.Duo.Utils; +using VisionBuilder.UI.Camera; namespace VisionBuilder.UI.Avalonia.Uno; @@ -79,10 +81,12 @@ public class App : Application ]; var avaloniaUiSettings = mainKernel.Get(); + var uiConfiguration = mainKernel.Get(); + var passwordInputService = mainKernel.Get(); settings.LoadSettings(); - desktop.MainWindow = new MainWindow(mainWindowVm, avaloniaUiSettings); + desktop.MainWindow = new MainWindow(mainWindowVm, avaloniaUiSettings, uiConfiguration, passwordInputService); } base.OnFrameworkInitializationCompleted(); diff --git a/VisionBuilder.UI.Avalonia.Uno/Program.cs b/VisionBuilder.UI.Avalonia.Uno/Program.cs index e4079e3..ef05783 100644 --- a/VisionBuilder.UI.Avalonia.Uno/Program.cs +++ b/VisionBuilder.UI.Avalonia.Uno/Program.cs @@ -1,5 +1,6 @@ using Avalonia; using Avalonia.LinuxFramebuffer; +using Serilog; namespace VisionBuilder.UI.Avalonia.Uno; @@ -8,6 +9,11 @@ public class Program [STAThread] public static void Main(string[] args) { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .WriteTo.Console() + .CreateLogger(); + if (args.Contains("--drm")) BuildAvaloniaApp().StartLinuxDrm(args, card: null, scaling: 1.0); else diff --git a/VisionBuilder.UI.Avalonia.Uno/Views/MainWindow.axaml b/VisionBuilder.UI.Avalonia.Uno/Views/MainWindow.axaml index 174aff1..4c410ec 100644 --- a/VisionBuilder.UI.Avalonia.Uno/Views/MainWindow.axaml +++ b/VisionBuilder.UI.Avalonia.Uno/Views/MainWindow.axaml @@ -20,6 +20,16 @@ HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="8"> +