diff --git a/src/App.xaml b/src/App.xaml index ae8d21b..9790576 100644 --- a/src/App.xaml +++ b/src/App.xaml @@ -14,4 +14,9 @@ --> + + + + + \ No newline at end of file diff --git a/src/LacmusApp.csproj b/src/LacmusApp.csproj index ccffa0c..e05c0a8 100644 --- a/src/LacmusApp.csproj +++ b/src/LacmusApp.csproj @@ -3,8 +3,8 @@ Exe netcoreapp3.1 Lacmus Foundation - 0.4.1.0 - 0.4.1.0 + 0.4.2.0 + 0.4.2.0 @@ -25,7 +25,6 @@ - diff --git a/src/Program.cs b/src/Program.cs index 160481f..56e0c9d 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -50,6 +50,17 @@ public static string GetVersion() private static AppBuilder BuildAvaloniaApp() { + //FOR TEST IN VirtualBox + /* + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + return AppBuilder.Configure() + .UsePlatformDetect() + .With(new Win32PlatformOptions {EnableMultitouch = true, AllowEglInitialization = true}) + .With(new AvaloniaNativePlatformOptions {UseGpu = false}) + .UseReactiveUI() + .LogToDebug(); + */ + return AppBuilder.Configure() .UsePlatformDetect() .With(new Win32PlatformOptions {EnableMultitouch = true, AllowEglInitialization = true}) diff --git a/src/Services/LocalizationContext.cs b/src/Services/LocalizationContext.cs index 48d58ea..34a1169 100644 --- a/src/Services/LocalizationContext.cs +++ b/src/Services/LocalizationContext.cs @@ -730,6 +730,13 @@ [Reactive] public string SaveAsCrops get { return _saveAsCrops; } set { this.RaiseAndSetIfChanged(ref _saveAsCrops, value); } } + + private string _saveAsSelectPath; + [Reactive] public string SaveAsSelectPath + { + get { return _saveAsSelectPath; } + set { this.RaiseAndSetIfChanged(ref _saveAsSelectPath, value); } + } #endregion @@ -924,6 +931,7 @@ private void UpdateText() ModelManagerActivateSelectedButton = "Activate selected"; ModelManagerDownloadSelectedButton = "Download selected"; ModelManagerApplyButton = "Apply"; + ModelManagerCloseButton = "Close"; ModelManagerRepositories = "Repositories"; ModelManagerRepositoryWatermark = "Enter repository name here."; ModelManagerAddRepositoryButton = "Add"; @@ -938,6 +946,7 @@ private void UpdateText() SaveAsXmlAnnotations = "Save XML annotations."; SaveAsDrawBbox = "Save photo with drawn bounded boxes."; SaveAsCrops = "Save bbox crops."; + SaveAsSelectPath = "Browse..."; //WizardSecondOutputWatermark = "Enter output path here."; //WizardSecondSavePhotosButton = "Save photos"; @@ -984,7 +993,7 @@ private void UpdateText() //Image Image="Изображение"; PredictAll="Обработать все"; - Increase="Увеличеть"; + Increase="Увеличить"; Shrink="Уменьшить"; Reset="Сбросить"; Next="Следующее"; @@ -1002,24 +1011,24 @@ private void UpdateText() //Context menu ShowGeoPosition="Показать геопозицию"; FavoritesStateString = "Добавить \\ удалить из избранных"; - + //About Window AboutAppName = "Приложение Lacmus."; AboutVersion = "Версия: "; AboutGintubPage = "Страница Github: "; AboutPoweredBy = "При поддержке: "; - AboutLicense = "Данное ПО поставляется АБСОЛЮТНО БЕЗ ГАРАНТИЙ; Это свободное ПО, оно распостраняется под лиценизией GNU GPL; Нажмите `Лицензия` для просмотра."; + AboutLicense = "Данное ПО поставляется АБСОЛЮТНО БЕЗ ГАРАНТИЙ; Это свободное ПО, оно распространяется под лицензией GNU GPL; Нажмите `Лицензия` для просмотра."; AboutLicenseButton = "Лицензия"; AboutGinhubButton = "Github"; AboutVisitWebSiteButton = "Веб-сайт"; - + //Wizard Window - WizardHeader = "Добро пожаловать в мастер распзнования фото!"; - WizardDescription1 = "Чтобы обработать фотографии с помощью нейронной сети (ml модели) вам необходимо выполнить 3 простых шага:"; - WizardDescription2 = " Шаг 1: выбирете фото для обработки"; - WizardDescription3 = " Шаг 2: выберете место для сохранения результатов"; + WizardHeader = "Добро пожаловать в мастер распознавания фото!"; + WizardDescription1 = "Чтобы обработать фотографии с помощью нейронной сети (ml модели) Вам необходимо выполнить 3 простых шага:"; + WizardDescription2 = " Шаг 1: выберите фото для обработки"; + WizardDescription3 = " Шаг 2: выберите место для сохранения результатов"; WizardDescription4 = " Шаг 3: выберите и настройте ml модель"; - WizardDescription5 = "В любое время вы можете загрыть это окно и веруться к основному интерфейсу программы. Спосибо что используете Lacmus!"; + WizardDescription5 = "В любое время вы можете закрыть это окно и вернуться к основному интерфейсу программы. Спасибо что используете Lacmus!"; WizardDescription6 = "Нажмите 'Далее' чтобы продолжить."; WizardBackButtonText = "Назад"; WizardNextButtonText = "Далее"; @@ -1032,17 +1041,17 @@ private void UpdateText() WizardFirstInputWatermark = "Введите путь к входной папке сюда."; WizardFirstOpenPhotosButton = "Выбрать фото"; //Page 2 - WizardSecondHeader = "Шаг 2: выберете выходные данные"; - WizardSecondDescription1 = "Теперь выберете папку для сознанения результатов, нажав на кнопку 'Сохранить фотографии' или введя полный путь к выходной папке в текстовом поле ниже."; - WizardSecondDescription2 = "После завершения процесса обработки приложение сохнанит результаты в выбранную папку. Вы сможете вновь открыть и просмотреть результаты в любой момент, выбрав меню 'Файл - Импортировать из XML'."; + WizardSecondHeader = "Шаг 2: выберите выходные данные"; + WizardSecondDescription1 = "Теперь выберите папку для сохранения результатов, нажав на кнопку 'Сохранить фотографии' или введя полный путь к выходной папке в текстовом поле ниже."; + WizardSecondDescription2 = "После завершения процесса обработки приложение сохранит результаты в выбранную папку. Вы сможете вновь открыть и просмотреть результаты в любой момент, выбрав меню 'Файл - Импортировать из XML'."; WizardSecondOutputWatermark = "Введите путь к выходной папке сюда."; WizardSecondSavePhotosButton = "Сохранить фотографии"; //Page 3 WizardThirdHeader = "Шаг 3: сконфигурируйте ml модель"; - WizardThirdDescription1 = "Перед началом обработки убедитесь что вы ml модель сконфигурирована правильо и готова к использованию."; - WizardThirdDescription2 = "Если ml модель не готова или вы хотите выбрать другую ml модель, сконфигурируйте ее выбрав меню 'Файл - Настройки'."; - WizardThirdDescription3 = "Если модель не готова, вы можете сконфигурировать и загрузить ее в менеджере моделей нажав кнопку 'Менеджер ml моделей'. Помните: для загрузки ml модели из Интернета необходимо загрузить от 2 до 6 GB. Убедитесь что ваше интернет соединение надежно и что на вашем компьютере присутсвует нобходимый объем дискового пространства."; - WizardThirdDescription4 = "Если все хорошо и модель готова - нажмите кнопку 'Начать обработку' чтобы запустить процесс. После завершения процесса распознования результаты будут сохранены в выбранной ранее выходной папке."; + WizardThirdDescription1 = "Перед началом обработки убедитесь, что ml модель сконфигурирована правильно и готова к использованию."; + WizardThirdDescription2 = "Если ml модель не готова, или Вы хотите выбрать другую ml модель, сконфигурируйте ее, выбрав меню 'Файл - Настройки'."; + WizardThirdDescription3 = "Если модель не готова, Вы можете сконфигурировать и загрузить ее в менеджере моделей, нажав кнопку 'Менеджер ml моделей'. Помните: для загрузки ml модели из Интернета необходимо загрузить от 2 до 6 GB. Убедитесь, что ваше интернет соединение надежно, и что на вашем компьютере присутствует необходимый объем дискового пространства."; + WizardThirdDescription4 = "Если все хорошо, и модель готова - нажмите кнопку 'Начать обработку', чтобы запустить процесс. После завершения процесса распознавания результаты будут сохранены в выбранной ранее выходной папке."; WizardThirdModelRepository = "Репозиторий ml модели: "; WizardThirdModelType = "Тип ml модели: "; WizardThirdModelVersion= "Версия ml модели: "; @@ -1050,23 +1059,23 @@ private void UpdateText() WizardThirdModelManagerButton = "Менеджер ml моделей"; WizardThirdModelStatusUpdateButton = "Обновить информацию"; //Page 4 - WizardFourthHeader = "Обработка фотографмй"; - WizardFourthDescription = "Выполняется процесс обработки изображений. Пожалуйста не закрывайте программу и дождитесь окончания процесса. Для принудительной остановки обработки нажчите кнопку 'Остановить ml модель' (весь прогресс будет сохранен)."; + WizardFourthHeader = "Обработка фотографий"; + WizardFourthDescription = "Выполняется процесс обработки изображений. Пожалуйста, не закрывайте программу и дождитесь окончания процесса. Для принудительной остановки обработки нажмите кнопку 'Остановить ml модель' (весь прогресс будет сохранен)."; WizardFourthTotalStatus = "Статус выполнения: "; WizardFourthLoadingPhotos = "Загрузка фотографий: "; WizardFourthProcessingPhotos = "Обработка фотографий: "; WizardFourthSavingResults = "Сохранение результатов: "; WizardFourthStopButton = "Остановить ml модель"; WizardFourthLogsExpander = "Детали обработки"; - + //Metadata - MetadataHeader = "GPS коордиаты центра изображения"; + MetadataHeader = "GPS координаты центра изображения"; MetadataLatitude = "Широта: "; MetadataLongitude = "Долгота: "; MetadataAltitude = "Высота: "; MetadataOpenWith = "Показать на карте:"; MetadataAllMetadata = "Все метаданные"; - + //Model manager ModelManagerApiVersion = "Версия API: "; ModelManagerInstalledModels = "Установленные ml модели"; @@ -1080,27 +1089,28 @@ private void UpdateText() ModelManagerRepositories = "Репозитории ml моделей"; ModelManagerRepositoryWatermark = "Ведите имя репозитория."; ModelManagerAddRepositoryButton = "Добавить"; - + //Save as - SaveAsOptionsToSave = "Выбирете опции для сохранения:"; - SaveAsTypesToSave = "Тип сохраняемых отографий:"; + SaveAsOptionsToSave = "Выберите опции для сохранения:"; + SaveAsTypesToSave = "Тип сохраняемых фотографий:"; SaveAsSourcePhotos = "Сохранить исходные фото."; SaveAsXmlAnnotations = "Сохранить XML аннотации."; SaveAsDrawBbox = "Сохранить фотографии с нарисованными рамками объектов."; - SaveAsCrops = "Сохранить вырезанные обьекты."; - + SaveAsCrops = "Сохранить вырезанные объекты."; + SaveAsSelectPath = "Выбрать папку"; + //Settings SettingsGeneral = "Общие"; SettingsLanguage = "Язык:"; - SettingsTheme = "Тема оффорления:"; + SettingsTheme = "Тема оформления:"; SettingsMlModel = "ML модель"; SettingsMlModelGeneral = "Общие настройки ml модели."; SettingsHost = "Хост:"; SettingsPort = "Порт:"; SettingsJWT = "Внешнее использование (включить JVT шифрование)"; - SettingsBatchSize = "Число потоков:"; + SettingsBatchSize = "Число потоков"; - //Settings window + //Erroes OsErrorMesageGPU = "Ваша операционная система не поддерживает этот тип ml моделей."; break; } diff --git a/src/ViewModels/AboutViewModel.cs b/src/ViewModels/AboutViewModel.cs index f9bec46..c8408d3 100644 --- a/src/ViewModels/AboutViewModel.cs +++ b/src/ViewModels/AboutViewModel.cs @@ -44,7 +44,7 @@ private void OpenUrl(string url) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - Process.Start(url); + Process.Start("cmd", $"/C start {url}"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { diff --git a/src/ViewModels/MainWindowViewModel.cs b/src/ViewModels/MainWindowViewModel.cs index 7ad7200..0921849 100644 --- a/src/ViewModels/MainWindowViewModel.cs +++ b/src/ViewModels/MainWindowViewModel.cs @@ -568,7 +568,7 @@ private void OpenUrl(string url) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - Process.Start(url); + Process.Start("cmd", $"/C start {url}"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { diff --git a/src/ViewModels/MetadataViewModel.cs b/src/ViewModels/MetadataViewModel.cs index 06503b8..360e0af 100644 --- a/src/ViewModels/MetadataViewModel.cs +++ b/src/ViewModels/MetadataViewModel.cs @@ -116,7 +116,7 @@ private void OpenUrl(string url) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - Process.Start(url); + Process.Start("cmd", $"/C start {url}"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { diff --git a/src/ViewModels/ModelManagerWindowViewModel.cs b/src/ViewModels/ModelManagerWindowViewModel.cs index 8136b93..d1d715e 100644 --- a/src/ViewModels/ModelManagerWindowViewModel.cs +++ b/src/ViewModels/ModelManagerWindowViewModel.cs @@ -9,11 +9,8 @@ using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Threading; -using Cudafy; -using Cudafy.Host; using Docker.DotNet.Models; using DynamicData; -using GASS.CUDA; using LacmusApp.Extensions; using LacmusApp.Managers; using LacmusApp.Models; @@ -320,6 +317,7 @@ public async Task DownloadModel() throw new Exception($"Incorrect OS for {SelectedAvailableModel.Type} inference type"); } + /* if (CudafyHost.GetDeviceCount(eGPUType.Emulator) == 0) { var msgbox = MessageBoxManager.GetMessageBoxStandardWindow(new MessageBoxStandardParams @@ -334,6 +332,7 @@ public async Task DownloadModel() var result = await msgbox.Show(); throw new Exception($"No CUDA devises."); } + */ } var config = new MLModelConfig(); diff --git a/src/ViewModels/SaveAsWindowViewModel.cs b/src/ViewModels/SaveAsWindowViewModel.cs index de17bf5..c96335f 100644 --- a/src/ViewModels/SaveAsWindowViewModel.cs +++ b/src/ViewModels/SaveAsWindowViewModel.cs @@ -34,8 +34,9 @@ public SaveAsWindowViewModel(Window window, SourceList photos, A viewModel => viewModel.OutputPath, Directory.Exists, path => $"Incorrect path {path}"); - - SaveCommand = ReactiveCommand.Create(SavePhotos); + + SelectPathCommand = ReactiveCommand.Create(SelectOutputFolder); + SaveCommand = ReactiveCommand.Create(SavePhotos, this.IsValid()); } [Reactive] public string OutputPath { get; set; } [Reactive] public int FilterIndex { get; set; } = 0; @@ -44,13 +45,13 @@ public SaveAsWindowViewModel(Window window, SourceList photos, A [Reactive] public bool IsDraw { get; set; } = false; [Reactive] public bool IsCrop { get; set; } = false; [Reactive] public LocalizationContext LocalizationContext { get; set; } + public ReactiveCommand SelectPathCommand { get; set; } public ReactiveCommand SaveCommand { get; set; } - - public async void SavePhotos() + + private async void SelectOutputFolder() { try { - _applicationStatusManager.ChangeCurrentAppStatus(Enums.Status.Working, ""); var dig = new OpenFolderDialog() { //TODO: Multi language support @@ -58,6 +59,19 @@ public async void SavePhotos() }; var dirPath = await dig.ShowAsync(new Window()); OutputPath = dirPath; + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + } + + private async void SavePhotos() + { + try + { + _applicationStatusManager.ChangeCurrentAppStatus(Enums.Status.Working, ""); if(!Directory.Exists(OutputPath)) throw new Exception($"No such directory: {OutputPath}."); diff --git a/src/Views/MainWindow.xaml b/src/Views/MainWindow.xaml index 765bfb7..3d56f9c 100644 --- a/src/Views/MainWindow.xaml +++ b/src/Views/MainWindow.xaml @@ -11,6 +11,11 @@ Title="LacmusApp" Width="800" Height="600"> + + + + + diff --git a/src/Views/SaveAsWindow.xaml b/src/Views/SaveAsWindow.xaml index a466f39..1fc29ad 100644 --- a/src/Views/SaveAsWindow.xaml +++ b/src/Views/SaveAsWindow.xaml @@ -27,7 +27,21 @@ -