From 37f71f405f199628fc03b9c02f573f603665ce1a Mon Sep 17 00:00:00 2001 From: Ruben Date: Sun, 8 Sep 2024 00:46:13 +0200 Subject: [PATCH] [Avalonia] Side by side fix rotation calculation #89. Refactoring, error handling, etc. --- src/PicView.Avalonia/CustomControls/PicBox.cs | 3 - .../ImageHandling/ImageHelper.cs | 16 ++++- src/PicView.Avalonia/UI/WindowHelper.cs | 46 ++++++++++++++- .../ImageSizeCalculationHelper.cs | 59 ++++++++++++++----- 4 files changed, 103 insertions(+), 21 deletions(-) diff --git a/src/PicView.Avalonia/CustomControls/PicBox.cs b/src/PicView.Avalonia/CustomControls/PicBox.cs index 47e18174..f1853183 100644 --- a/src/PicView.Avalonia/CustomControls/PicBox.cs +++ b/src/PicView.Avalonia/CustomControls/PicBox.cs @@ -359,9 +359,6 @@ private void RenderImageSideBySide(DrawingContext context, IImage source, IImage return; } - // Scale the first image to fit within the remaining width while keeping the same height - var scaledSourceSize = new Size(firstImageWidth, sourceSize.Height * scale); - // Calculate the destination rectangles for both images var sourceDestRect = new Rect(0, 0, firstImageWidth, viewPort.Height); var secondaryDestRect = new Rect(firstImageWidth, 0, SecondaryImageWidth, viewPort.Height); diff --git a/src/PicView.Avalonia/ImageHandling/ImageHelper.cs b/src/PicView.Avalonia/ImageHandling/ImageHelper.cs index 221b6398..d6097e20 100644 --- a/src/PicView.Avalonia/ImageHandling/ImageHelper.cs +++ b/src/PicView.Avalonia/ImageHandling/ImageHelper.cs @@ -138,6 +138,13 @@ public static class ImageHelper private static async Task AddImageAsync(FileInfo fileInfo, ImageModel imageModel) { + if (fileInfo is null) + { +#if DEBUG + Console.WriteLine($"Error: {nameof(ImageHelper)}:{nameof(AddImageAsync)}: {nameof(fileInfo)} is null"); +#endif + return; + } const int bufferSize = 4096; await using var fs = new FileStream( fileInfo.FullName, @@ -177,8 +184,6 @@ private static async Task AddDefaultImageAsync(FileInfo fileInfo, ImageModel ima Add(memoryStream, imageModel); } } - - #endregion @@ -186,6 +191,13 @@ private static async Task AddDefaultImageAsync(FileInfo fileInfo, ImageModel ima private static void Add(Stream stream, ImageModel imageModel) { + if (stream is null) + { +#if DEBUG + Console.WriteLine($"Error: {nameof(ImageHelper)}:{nameof(Add)}: {nameof(stream)} is null"); +#endif + return; + } var bitmap = new Bitmap(stream); imageModel.Image = bitmap; imageModel.PixelWidth = bitmap?.PixelSize.Width ?? 0; diff --git a/src/PicView.Avalonia/UI/WindowHelper.cs b/src/PicView.Avalonia/UI/WindowHelper.cs index 1078d141..5dbe5a73 100644 --- a/src/PicView.Avalonia/UI/WindowHelper.cs +++ b/src/PicView.Avalonia/UI/WindowHelper.cs @@ -4,6 +4,7 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input; using Avalonia.Threading; +using ImageMagick; using PicView.Avalonia.Keybindings; using PicView.Avalonia.Navigation; using PicView.Avalonia.ViewModels; @@ -11,6 +12,7 @@ using PicView.Core.Calculations; using PicView.Core.Config; using PicView.Core.FileHandling; +using PicView.Core.Navigation; namespace PicView.Avalonia.UI; @@ -418,18 +420,58 @@ public static void SetSize(MainViewModel vm) return; } + double firstWidth, firstHeight; var preloadValue = vm.ImageIterator?.GetCurrentPreLoadValue(); + if (preloadValue == null) + { + var magickImage = new MagickImage(); + magickImage.Ping(vm.FileInfo); + firstWidth = magickImage.Width; + firstHeight = magickImage.Height; + } + else + { + firstWidth = GetWidth(preloadValue); + firstHeight = GetHeight(preloadValue); + } if (SettingsHelper.Settings.ImageScaling.ShowImageSideBySide) { var secondaryPreloadValue = vm.ImageIterator?.GetNextPreLoadValue(); + double secondWidth, secondHeight; if (secondaryPreloadValue != null) { - SetSize(preloadValue?.ImageModel?.PixelWidth ?? vm.ImageWidth, preloadValue?.ImageModel?.PixelHeight ?? vm.ImageHeight, secondaryPreloadValue.ImageModel?.PixelWidth ?? vm.ImageWidth, secondaryPreloadValue.ImageModel?.PixelHeight ?? vm.ImageHeight, vm.RotationAngle, vm); + secondWidth = GetWidth(secondaryPreloadValue); + secondHeight = GetHeight(secondaryPreloadValue); } + else if (vm.ImageIterator is not null) + { + var nextIndex = vm.ImageIterator.GetIteration(vm.ImageIterator.CurrentIndex, vm.ImageIterator.IsReversed ? NavigateTo.Previous : NavigateTo.Next); + var magickImage = new MagickImage(); + magickImage.Ping(vm.ImageIterator.ImagePaths[nextIndex]); + secondWidth = magickImage.Width; + secondHeight = magickImage.Height; + } + else + { + secondWidth = 0; + secondHeight = 0; + } + SetSize(firstWidth, firstHeight, secondWidth, secondHeight, vm.RotationAngle, vm); } else { - SetSize(preloadValue?.ImageModel?.PixelWidth ?? vm.ImageWidth, preloadValue?.ImageModel?.PixelHeight ?? vm.ImageHeight, 0, 0, vm.RotationAngle, vm); + SetSize(firstWidth, firstHeight, 0, 0, vm.RotationAngle, vm); + } + + return; + double GetWidth(PreLoader.PreLoadValue preloadValue) + { + return preloadValue?.ImageModel?.PixelWidth ?? vm.ImageWidth; + } + + double GetHeight(PreLoader.PreLoadValue preloadValue) + { + return preloadValue?.ImageModel?.PixelHeight ?? vm.ImageHeight; } } diff --git a/src/PicView.Core/Calculations/ImageSizeCalculationHelper.cs b/src/PicView.Core/Calculations/ImageSizeCalculationHelper.cs index 79a6e49c..bb17f69e 100644 --- a/src/PicView.Core/Calculations/ImageSizeCalculationHelper.cs +++ b/src/PicView.Core/Calculations/ImageSizeCalculationHelper.cs @@ -203,29 +203,60 @@ public static ImageSize GetImageSize(double width, { var widthPadding = SettingsHelper.Settings.ImageScaling.StretchImage ? 4 : padding; var availableWidth = monitorWidth - widthPadding; - - // If combined width exceeds available width, scale both images down proportionally - if (combinedWidth > availableWidth) + var availableHeight = monitorHeight - (widthPadding + uiBottomSize + uiTopSize); + if (rotationAngle is 0 or 180) { - var scaleFactor = availableWidth / combinedWidth; - xWidth1 *= scaleFactor; - xWidth2 *= scaleFactor; - xHeight *= scaleFactor; + // If combined width exceeds available width, scale both images down proportionally + if (combinedWidth > availableWidth) + { + var scaleFactor = availableWidth / combinedWidth; + xWidth1 *= scaleFactor; + xWidth2 *= scaleFactor; + xHeight *= scaleFactor; - combinedWidth = xWidth1 + xWidth2; + combinedWidth = xWidth1 + xWidth2; + } + } + else + { + if (combinedWidth > availableHeight) + { + var scaleFactor = availableHeight / combinedWidth; + xWidth1 *= scaleFactor; + xWidth2 *= scaleFactor; + xHeight *= scaleFactor; + + combinedWidth = xWidth1 + xWidth2; + } } } else { - if (combinedWidth > containerWidth) + if (rotationAngle is 0 or 180) { - var scaleFactor = containerWidth / combinedWidth; - xWidth1 *= scaleFactor; - xWidth2 *= scaleFactor; - xHeight *= scaleFactor; + if (combinedWidth > containerWidth) + { + var scaleFactor = containerWidth / combinedWidth; + xWidth1 *= scaleFactor; + xWidth2 *= scaleFactor; + xHeight *= scaleFactor; - combinedWidth = xWidth1 + xWidth2; + combinedWidth = xWidth1 + xWidth2; + } + } + else + { + if (combinedWidth > containerHeight) + { + var scaleFactor = containerHeight / combinedWidth; + xWidth1 *= scaleFactor; + xWidth2 *= scaleFactor; + xHeight *= scaleFactor; + + combinedWidth = xWidth1 + xWidth2; + } } + } double scrollWidth, scrollHeight;