feat: Add Face Matcher functionality and related settings
- Implemented FilePathToBitmapConverter for image loading. - Enhanced DataModel with commands and properties for Face Matcher. - Created FaceMatcherResultItem model to store results. - Updated SettingsDto to include Face Matcher paths and tolerance. - Introduced PickerPreferenceService for managing folder paths. - Expanded AiSettingsViewModel to manage Face Matcher settings and results.
This commit is contained in:
parent
f57dc1edba
commit
c261557a29
10 changed files with 2041 additions and 192 deletions
|
|
@ -5,6 +5,8 @@ using Avalonia.Layout;
|
|||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Styling;
|
||||
using Avalonia.Threading;
|
||||
using ImageCatalog_2.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
|
||||
|
|
@ -13,6 +15,7 @@ namespace ImageCatalog_2;
|
|||
public partial class AvaloniaMainWindow : Window
|
||||
{
|
||||
private readonly DataModel _model;
|
||||
private readonly PickerPreferenceService _pickerPreferenceService;
|
||||
private bool _isDarkTheme;
|
||||
|
||||
public AvaloniaMainWindow(DataModel model)
|
||||
|
|
@ -20,6 +23,7 @@ public partial class AvaloniaMainWindow : Window
|
|||
InitializeComponent();
|
||||
|
||||
_model = model;
|
||||
_pickerPreferenceService = Program.ServiceProvider.GetRequiredService<PickerPreferenceService>();
|
||||
DataContext = _model;
|
||||
|
||||
Opened += (_, _) => SyncThemeStateFromCurrentTheme();
|
||||
|
|
@ -30,35 +34,43 @@ public partial class AvaloniaMainWindow : Window
|
|||
|
||||
_model.SelectSourceFolderRequested += async (_, _) =>
|
||||
{
|
||||
var suggestedStartLocation = await _pickerPreferenceService.TryGetStartFolderAsync(StorageProvider, PickerPreferenceKeys.SourceFolder, _model.SourcePath);
|
||||
var folders = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = "Seleziona cartella sorgente"
|
||||
Title = "Seleziona cartella sorgente",
|
||||
SuggestedStartLocation = suggestedStartLocation
|
||||
});
|
||||
|
||||
if (folders.Count > 0)
|
||||
{
|
||||
_model.SourcePath = folders[0].Path.LocalPath + Path.DirectorySeparatorChar;
|
||||
_pickerPreferenceService.RememberPath(PickerPreferenceKeys.SourceFolder, _model.SourcePath);
|
||||
}
|
||||
};
|
||||
|
||||
_model.SelectDestinationFolderRequested += async (_, _) =>
|
||||
{
|
||||
var suggestedStartLocation = await _pickerPreferenceService.TryGetStartFolderAsync(StorageProvider, PickerPreferenceKeys.DestinationFolder, _model.DestinationPath);
|
||||
var folders = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = "Seleziona cartella destinazione"
|
||||
Title = "Seleziona cartella destinazione",
|
||||
SuggestedStartLocation = suggestedStartLocation
|
||||
});
|
||||
|
||||
if (folders.Count > 0)
|
||||
{
|
||||
_model.DestinationPath = folders[0].Path.LocalPath + Path.DirectorySeparatorChar;
|
||||
_pickerPreferenceService.RememberPath(PickerPreferenceKeys.DestinationFolder, _model.DestinationPath);
|
||||
}
|
||||
};
|
||||
|
||||
_model.SelectLogoFileRequested += async (_, _) =>
|
||||
{
|
||||
var suggestedStartLocation = await _pickerPreferenceService.TryGetStartFolderAsync(StorageProvider, PickerPreferenceKeys.LogoFile, _model.LogoFile);
|
||||
var files = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = "Seleziona logo",
|
||||
SuggestedStartLocation = suggestedStartLocation,
|
||||
FileTypeFilter =
|
||||
[
|
||||
new FilePickerFileType("Immagini") { Patterns = ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif"] }
|
||||
|
|
@ -68,34 +80,41 @@ public partial class AvaloniaMainWindow : Window
|
|||
if (files.Count > 0)
|
||||
{
|
||||
_model.LogoFile = files[0].Path.LocalPath;
|
||||
_pickerPreferenceService.RememberPath(PickerPreferenceKeys.LogoFile, _model.LogoFile);
|
||||
}
|
||||
};
|
||||
|
||||
_model.SelectModelsFolderRequested += async (_, _) =>
|
||||
{
|
||||
var suggestedStartLocation = await _pickerPreferenceService.TryGetStartFolderAsync(StorageProvider, PickerPreferenceKeys.ModelsFolder, _model.ModelsFolderPath);
|
||||
var folders = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = "Seleziona cartella modelli"
|
||||
Title = "Seleziona cartella modelli",
|
||||
SuggestedStartLocation = suggestedStartLocation
|
||||
});
|
||||
|
||||
if (folders.Count > 0)
|
||||
{
|
||||
_model.ModelsFolderPath = folders[0].Path.LocalPath + Path.DirectorySeparatorChar;
|
||||
_pickerPreferenceService.RememberPath(PickerPreferenceKeys.ModelsFolder, _model.ModelsFolderPath);
|
||||
}
|
||||
};
|
||||
|
||||
_model.SelectCsvOutputRequested += async (_, _) =>
|
||||
{
|
||||
var suggestedStartLocation = await _pickerPreferenceService.TryGetStartFolderAsync(StorageProvider, PickerPreferenceKeys.CsvOutput, _model.CsvOutputPath);
|
||||
var file = await StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
||||
{
|
||||
Title = "Salva CSV",
|
||||
DefaultExtension = "csv",
|
||||
FileTypeChoices = [new FilePickerFileType("CSV") { Patterns = ["*.csv"] }]
|
||||
FileTypeChoices = [new FilePickerFileType("CSV") { Patterns = ["*.csv"] }],
|
||||
SuggestedStartLocation = suggestedStartLocation
|
||||
});
|
||||
|
||||
if (file is not null)
|
||||
{
|
||||
_model.CsvOutputPath = file.Path.LocalPath;
|
||||
_pickerPreferenceService.RememberPath(PickerPreferenceKeys.CsvOutput, _model.CsvOutputPath);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -148,7 +167,7 @@ public partial class AvaloniaMainWindow : Window
|
|||
|
||||
private async void AvaloniaMainWindow_Closing(object? sender, CancelEventArgs e)
|
||||
{
|
||||
if (_isStoppingFaceEncoderForClose || !_model.IsFaceEncoderRunning)
|
||||
if (_isStoppingFaceEncoderForClose || (!_model.IsFaceEncoderRunning && !_model.IsFaceMatcherRunning))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -158,7 +177,15 @@ public partial class AvaloniaMainWindow : Window
|
|||
|
||||
try
|
||||
{
|
||||
await _model.StopFaceEncoderAsync("Arresto face encoder in chiusura...", waitForExit: true);
|
||||
if (_model.IsFaceMatcherRunning)
|
||||
{
|
||||
await _model.StopFaceMatcherAsync("Arresto face matcher in chiusura...", waitForExit: true);
|
||||
}
|
||||
|
||||
if (_model.IsFaceEncoderRunning)
|
||||
{
|
||||
await _model.StopFaceEncoderAsync("Arresto face encoder in chiusura...", waitForExit: true);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue