feat: Update FaceAiTabView to support output file selection and validation for .pkl files
This commit is contained in:
parent
41d9dacfac
commit
fa09f7c324
2 changed files with 83 additions and 19 deletions
|
|
@ -4,7 +4,7 @@
|
|||
<ScrollViewer>
|
||||
<StackPanel Margin="4" Spacing="6">
|
||||
<TextBlock Text="Face Recognition Encoder" FontWeight="Bold" />
|
||||
<TextBlock Text="Esegue face_encoder.exe usando la cartella Destinazione corrente come --images."
|
||||
<TextBlock Text="Esegue face_encoder.exe usando la cartella Destinazione corrente come --images e un file .pkl come --out."
|
||||
TextWrapping="Wrap" Opacity="0.8" />
|
||||
|
||||
<TextBlock Text="Eseguibile" FontWeight="Bold" Margin="0,4,0,0" />
|
||||
|
|
@ -15,11 +15,17 @@
|
|||
<Button Grid.Column="3" Name="FaceOpenExecutableButton" Content="Apri" Click="OpenFaceExecutableFolder_Click" Width="56" Margin="6,0,0,0" />
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="Auto,*,Auto,Auto" ColumnSpacing="6">
|
||||
<TextBlock Grid.Column="0" Text="Sorgente:" VerticalAlignment="Center" />
|
||||
<TextBox Grid.Column="1" Name="FaceDestinationPathTextBox" Text="{Binding DestinationPath, Mode=OneWay}" IsReadOnly="True" />
|
||||
<Button Grid.Column="3" Name="FaceOpenDestinationButton" Content="Apri" Click="OpenFaceDestinationFolder_Click" Width="56" Margin="6,0,0,0" />
|
||||
</Grid>
|
||||
|
||||
<TextBlock Text="Output encodings" FontWeight="Bold" Margin="0,4,0,0" />
|
||||
<Grid ColumnDefinitions="Auto,*,Auto,Auto" ColumnSpacing="6">
|
||||
<TextBlock Grid.Column="0" Text="Cartella out:" VerticalAlignment="Center" />
|
||||
<TextBox Grid.Column="1" Name="FaceOutputFolderTextBox" Text="{Binding FaceOutputFolderPath, Mode=TwoWay}" Watermark="C:\\output\\encodings" />
|
||||
<Button Grid.Column="2" Name="FaceSelectOutputButton" Content="Scegli..." Click="SelectFaceOutputFolder_Click" Width="88" Margin="6,0,0,0" />
|
||||
<TextBlock Grid.Column="0" Text="File out (.pkl):" VerticalAlignment="Center" />
|
||||
<TextBox Grid.Column="1" Name="FaceOutputFolderTextBox" Text="{Binding FaceOutputFolderPath, Mode=TwoWay}" Watermark="C:\\output\\encodings.pkl" />
|
||||
<Button Grid.Column="2" Name="FaceSelectOutputButton" Content="Scegli..." Click="SelectFaceOutputFile_Click" Width="88" Margin="6,0,0,0" />
|
||||
<Button Grid.Column="3" Name="FaceOpenOutputButton" Content="Apri" Click="OpenFaceOutputFolder_Click" Width="56" Margin="6,0,0,0" />
|
||||
</Grid>
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public partial class FaceAiTabView : Avalonia.Controls.UserControl
|
|||
}
|
||||
}
|
||||
|
||||
private async void SelectFaceOutputFolder_Click(object? sender, RoutedEventArgs e)
|
||||
private async void SelectFaceOutputFile_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var outputBox = this.FindControl<Avalonia.Controls.TextBox>("FaceOutputFolderTextBox");
|
||||
if (outputBox is null)
|
||||
|
|
@ -72,14 +72,21 @@ public partial class FaceAiTabView : Avalonia.Controls.UserControl
|
|||
return;
|
||||
}
|
||||
|
||||
var folders = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
var files = await storageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
||||
{
|
||||
Title = "Seleziona cartella output encodings"
|
||||
Title = "Seleziona file output encodings (.pkl)",
|
||||
SuggestedFileName = "encodings.pkl",
|
||||
DefaultExtension = "pkl",
|
||||
FileTypeChoices =
|
||||
[
|
||||
new FilePickerFileType("Pickle file") { Patterns = ["*.pkl"] }
|
||||
],
|
||||
ShowOverwritePrompt = true
|
||||
});
|
||||
|
||||
if (folders.Count > 0)
|
||||
if (files is not null)
|
||||
{
|
||||
outputBox.Text = folders[0].Path.LocalPath;
|
||||
outputBox.Text = files.Path.LocalPath;
|
||||
if (DataContext is DataModel model)
|
||||
{
|
||||
model.FaceOutputFolderPath = outputBox.Text;
|
||||
|
|
@ -119,7 +126,38 @@ public partial class FaceAiTabView : Avalonia.Controls.UserControl
|
|||
return;
|
||||
}
|
||||
|
||||
OpenInExplorer(outputBox.Text);
|
||||
var outputPath = outputBox.Text?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(outputPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (File.Exists(outputPath))
|
||||
{
|
||||
OpenInExplorer(outputPath);
|
||||
return;
|
||||
}
|
||||
|
||||
var directory = Path.GetDirectoryName(outputPath);
|
||||
OpenInExplorer(string.IsNullOrWhiteSpace(directory) ? outputPath : directory);
|
||||
}
|
||||
|
||||
private void OpenFaceDestinationFolder_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var destBox = this.FindControl<Avalonia.Controls.TextBox>("FaceDestinationPathTextBox");
|
||||
string? path = destBox?.Text?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(path) && DataContext is DataModel model)
|
||||
{
|
||||
path = (model.DestinationPath ?? string.Empty).Trim();
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var directory = Path.GetDirectoryName(path);
|
||||
OpenInExplorer(string.IsNullOrWhiteSpace(directory) ? path : directory);
|
||||
}
|
||||
|
||||
private async void RunFaceEncoder_Click(object? sender, RoutedEventArgs e)
|
||||
|
|
@ -142,11 +180,11 @@ public partial class FaceAiTabView : Avalonia.Controls.UserControl
|
|||
}
|
||||
|
||||
var executablePath = executableBox.Text?.Trim().Trim('"') ?? string.Empty;
|
||||
var outputFolder = outputFolderBox.Text?.Trim().Trim('"') ?? string.Empty;
|
||||
var outputFilePath = outputFolderBox.Text?.Trim().Trim('"') ?? string.Empty;
|
||||
var imagesFolder = (model.DestinationPath ?? string.Empty).Trim().Trim('"');
|
||||
|
||||
model.FaceExecutablePath = executablePath;
|
||||
model.FaceOutputFolderPath = outputFolder;
|
||||
model.FaceOutputFolderPath = outputFilePath;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(executablePath) || !File.Exists(executablePath))
|
||||
{
|
||||
|
|
@ -160,20 +198,30 @@ public partial class FaceAiTabView : Avalonia.Controls.UserControl
|
|||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(outputFolder))
|
||||
if (string.IsNullOrWhiteSpace(outputFilePath))
|
||||
{
|
||||
statusBlock.Text = "Inserisci la cartella di output.";
|
||||
statusBlock.Text = "Inserisci il file di output .pkl.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.Equals(Path.GetExtension(outputFilePath), ".pkl", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
statusBlock.Text = "Il file di output deve avere estensione .pkl.";
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(outputFolder);
|
||||
var outputDirectory = Path.GetDirectoryName(outputFilePath);
|
||||
if (!string.IsNullOrWhiteSpace(outputDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(outputDirectory);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Unable to create face output folder: {OutputFolder}", outputFolder);
|
||||
statusBlock.Text = "Impossibile creare la cartella di output.";
|
||||
_logger.LogError(ex, "Unable to create face output directory for file: {OutputFilePath}", outputFilePath);
|
||||
statusBlock.Text = "Impossibile creare la cartella del file di output.";
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +235,7 @@ public partial class FaceAiTabView : Avalonia.Controls.UserControl
|
|||
try
|
||||
{
|
||||
var imagesFolderArg = NormalizeDirectoryPathArgument(imagesFolder);
|
||||
var outputFolderArg = NormalizeDirectoryPathArgument(outputFolder);
|
||||
var outputFileArg = NormalizeFilePathArgument(outputFilePath);
|
||||
|
||||
var processStartInfo = new ProcessStartInfo
|
||||
{
|
||||
|
|
@ -201,7 +249,7 @@ public partial class FaceAiTabView : Avalonia.Controls.UserControl
|
|||
processStartInfo.ArgumentList.Add("--images");
|
||||
processStartInfo.ArgumentList.Add(imagesFolderArg);
|
||||
processStartInfo.ArgumentList.Add("--out");
|
||||
processStartInfo.ArgumentList.Add(outputFolderArg);
|
||||
processStartInfo.ArgumentList.Add(outputFileArg);
|
||||
|
||||
using var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true };
|
||||
process.OutputDataReceived += (_, args) =>
|
||||
|
|
@ -314,4 +362,14 @@ public partial class FaceAiTabView : Avalonia.Controls.UserControl
|
|||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private static string NormalizeFilePathArgument(string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return value.Trim().Trim('"');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue