feat: safe image loading

add AsyncImageViewModel that loading images sequentially
This commit is contained in:
2026-03-05 09:32:24 +03:00
parent fe46722d55
commit d7c0883e6b
3 changed files with 112 additions and 27 deletions
@@ -39,7 +39,7 @@ public partial class AmineContentSeparatorCalibrationViewModel : ViewModelBase
[ObservableProperty] private Task? _captureImagesTask = null;
[ObservableProperty] private ObservableCollection<KeyValuePair<IImage, ImageRecord>> _images = new();
[ObservableProperty] private ObservableCollection<AsyncImageRecordViewModel> _images = new();
[ObservableProperty] private bool _imagesIsCapturing = false;
[ObservableProperty] private string _imagesCapturingProgress = "";
[ObservableProperty] private int _imagesSectionCurrentIndex = 0;
@@ -88,12 +88,16 @@ public partial class AmineContentSeparatorCalibrationViewModel : ViewModelBase
partial void OnEditingRecordChanged(SeparatorRecord value)
{
var images = value.Images
.ToAsyncEnumerable()
.Select(i => new KeyValuePair<string?, ImageRecord>(_imageStorageService.GetFullPath(i.ImagePath, "separator"), i))
.Where(kv => kv.Key is not null)
.Select(kv => new KeyValuePair<IImage, ImageRecord>(new Bitmap(kv.Key!), kv.Value));
.Select(i =>
{
var path = _imageStorageService.GetFullPath(i.ImagePath, "separator");
if (path is null)
return null;
return new AsyncImageRecordViewModel(path, i);
})
.OfType<AsyncImageRecordViewModel>();
Images = new(images.ToBlockingEnumerable());
Images = new(images);
}
[RelayCommand] private void ToggleMenu() => IsMenuOpen = !IsMenuOpen;
@@ -277,10 +281,14 @@ public partial class AmineContentSeparatorCalibrationViewModel : ViewModelBase
_illuminatorService.TurnOff();
var images = imageRecords
.ToAsyncEnumerable()
.Select(i => new KeyValuePair<string?, ImageRecord>(_imageStorageService.GetFullPath(i.ImagePath, "separator"), i))
.Where(kv => kv.Key is not null)
.Select(kv => new KeyValuePair<IImage, ImageRecord>(new Bitmap(kv.Key!), kv.Value));
.Select(i =>
{
var path = _imageStorageService.GetFullPath(i.ImagePath, "separator");
if (path is null)
return null;
return new AsyncImageRecordViewModel(path, i);
})
.OfType<AsyncImageRecordViewModel>();
Dispatcher.UIThread.Invoke(() =>
{
@@ -288,7 +296,7 @@ public partial class AmineContentSeparatorCalibrationViewModel : ViewModelBase
EditingRecord.Images.AddRange(imageRecords);
Images.Clear();
Images = new(images.ToBlockingEnumerable());
Images = new(images);
});
}
catch (TaskCanceledException)