Browse Source

Progress to image loading #66 and test screen #80

Ruben 4 năm trước cách đây
mục cha
commit
97612b7721

+ 58 - 0
src/PicView.Data/Imaging/ImageDecoder.cs

@@ -0,0 +1,58 @@
+using Avalonia.Media.Imaging;
+
+namespace PicView.Data.Imaging
+{
+    public static class ImageDecoder
+    {
+        /// <summary>
+        /// Decodes image from file to relevant image
+        /// </summary>
+        /// <param name="fileInfo">Cannot be null</param>
+        /// <returns></returns>
+        public static async Task<Avalonia.Media.IImage?> ReturnPicAsync(FileInfo fileInfo)
+        {
+            if (fileInfo == null) { return null; }
+            if (fileInfo.Length <= 0) { return null; }
+
+            switch (fileInfo.Extension)
+            {
+                case { } when fileInfo.Extension.Equals(".jpg", StringComparison.OrdinalIgnoreCase):
+                case { } when fileInfo.Extension.Equals(".jpeg", StringComparison.OrdinalIgnoreCase):
+                case { } when fileInfo.Extension.Equals(".jpe", StringComparison.OrdinalIgnoreCase):
+                case { } when fileInfo.Extension.Equals(".png", StringComparison.OrdinalIgnoreCase):
+                case { } when fileInfo.Extension.Equals(".bmp", StringComparison.OrdinalIgnoreCase):
+                case { } when fileInfo.Extension.Equals(".gif", StringComparison.OrdinalIgnoreCase):
+                case { } when fileInfo.Extension.Equals(".jfif", StringComparison.OrdinalIgnoreCase):
+                case { } when fileInfo.Extension.Equals(".ico", StringComparison.OrdinalIgnoreCase):
+                case { } when fileInfo.Extension.Equals(".webp", StringComparison.OrdinalIgnoreCase):
+                case { } when fileInfo.Extension.Equals(".wbmp", StringComparison.OrdinalIgnoreCase):
+                    return await Task.FromResult(GetBitmap(fileInfo)).ConfigureAwait(false);
+
+                default:
+                    return null;
+            }
+        }
+
+        private static Bitmap? GetBitmap(FileInfo fileInfo)
+        {
+            try
+            {
+                if (fileInfo == null)
+                {
+                    throw new ArgumentNullException(nameof(fileInfo));
+                }
+
+                using var filestream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, true);
+                var image = new Bitmap(filestream);
+                return image;
+            }
+            catch (Exception e)
+            {
+#if DEBUG
+                System.Diagnostics.Trace.WriteLine($"{nameof(GetBitmap)} {fileInfo?.Name} exception, \n {e.Message}");
+#endif
+                return null;
+            }
+        }
+    }
+}

+ 15 - 0
src/PicView.Data/Screen/ScreenHelper.cs

@@ -0,0 +1,15 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.LogicalTree;
+
+namespace PicView.Data.Screen;
+
+public static class ScreenHelper
+{
+    public static Avalonia.Platform.Screen GetScreen(Control control)
+    {
+        var window = control.GetSelfAndLogicalAncestors().OfType<Window>().First();
+            
+        return window.Screens.ScreenFromPoint(new PixelPoint());
+    }
+}

+ 25 - 0
src/PicView.Data/Sizing/ImageSizeHelper.cs

@@ -0,0 +1,25 @@
+using Avalonia;
+using Avalonia.Controls;
+
+namespace PicView.Data.Sizing;
+
+public static class ImageSize
+{
+    public static Size GetScaledImageSize(double width, double height, Control control)
+    {
+        if (width <= 0 || height <= 0) { return new Size(0,0); }
+
+        double maxWidth, maxHeight;
+        var screen = Screen.ScreenHelper.GetScreen(control);
+
+        var padding = 70;
+        
+        maxWidth = Math.Min(screen.WorkingArea.Width - padding, width);
+        maxHeight = Math.Min(screen.WorkingArea.Height - padding, height);
+        
+        var aspectRatio = Math.Min(maxWidth / width, maxHeight / height);
+
+        return new Size(width * aspectRatio, height * aspectRatio);
+
+    }
+}

+ 0 - 1
src/PicView.Win32/PicView.Win32.csproj

@@ -9,7 +9,6 @@
   <ItemGroup>
   <ItemGroup>
     <Folder Include="LockScreen\" />
     <Folder Include="LockScreen\" />
     <Folder Include="Explorer\" />
     <Folder Include="Explorer\" />
-    <Folder Include="Screen\" />
     <Folder Include="Wallpaper\" />
     <Folder Include="Wallpaper\" />
   </ItemGroup>
   </ItemGroup>
 
 

+ 0 - 1
src/PicView/PicView.csproj

@@ -29,7 +29,6 @@
 		<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
 		<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
 		<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.11-rc.2" />
 		<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.11-rc.2" />
 		<PackageReference Include="Avalonia.SKPictureImage" Version="0.10.6.1" />
 		<PackageReference Include="Avalonia.SKPictureImage" Version="0.10.6.1" />
-		<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.11.2-rc.2" />
 		<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
 		<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
 	</ItemGroup>
 	</ItemGroup>
 	<ItemGroup>
 	<ItemGroup>

+ 21 - 5
src/PicView/ViewModels/MainWindowViewModel.cs

@@ -1,9 +1,9 @@
-using System.Reactive;
-using Avalonia.Controls.ApplicationLifetimes;
+using System.Drawing;
 using ReactiveUI;
 using ReactiveUI;
 using System.Windows.Input;
 using System.Windows.Input;
 using Avalonia.Controls;
 using Avalonia.Controls;
 using Avalonia.Media;
 using Avalonia.Media;
+using Size = Avalonia.Size;
 
 
 namespace PicView.ViewModels
 namespace PicView.ViewModels
 {
 {
@@ -25,7 +25,10 @@ namespace PicView.ViewModels
                 if (pic is not null)
                 if (pic is not null)
                 {
                 {
                     Pic = pic;
                     Pic = pic;
-                    Title = "Loaded";
+                    var size = Data.Sizing.ImageSize.GetScaledImageSize(pic.Size.Width, pic.Size.Height, window);
+                    Width = size.Width;
+                    Height = size.Height;
+                    Title = $"{size.Width} x {size.Height}";
                 }
                 }
                 else
                 else
                 {
                 {
@@ -45,13 +48,26 @@ namespace PicView.ViewModels
             set => this.RaiseAndSetIfChanged(ref _title, value);
             set => this.RaiseAndSetIfChanged(ref _title, value);
         }
         }
         
         
-        private IImage _pic;
-        public IImage Pic
+        private IImage? _pic;
+        public IImage? Pic
         {
         {
             get => _pic;
             get => _pic;
             set => this.RaiseAndSetIfChanged(ref _pic, value);
             set => this.RaiseAndSetIfChanged(ref _pic, value);
         }
         }
 
 
+        private double _width;
+        public double Width
+        {
+            get => _width;
+            set => this.RaiseAndSetIfChanged(ref _width, value);
+        }
+        
+        private double _height;
+        public double Height
+        {
+            get => _height;
+            set => this.RaiseAndSetIfChanged(ref _height, value);
+        }
 
 
 
 
     }
     }

+ 7 - 2
src/PicView/Views/MainWindow.axaml

@@ -13,7 +13,8 @@
     WindowStartupLocation="CenterScreen"
     WindowStartupLocation="CenterScreen"
     x:Class="PicView.Views.MainWindow"
     x:Class="PicView.Views.MainWindow"
     xmlns="https://github.com/avaloniaui"
     xmlns="https://github.com/avaloniaui"
-    xmlns:customTitleBars="clr-namespace:PicView.Views.CustomTitleBars" Opened="TopLevel_OnOpened"
+    xmlns:customTitleBars="clr-namespace:PicView.Views.CustomTitleBars" 
+    Opened="TopLevel_OnOpened"
     xmlns:uc="using:PicView.CustomControls"
     xmlns:uc="using:PicView.CustomControls"
     xmlns:vm="using:PicView.ViewModels"
     xmlns:vm="using:PicView.ViewModels"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
@@ -189,7 +190,11 @@
             
             
             <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
             <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
                 <Border x:Name="ImageBorder">
                 <Border x:Name="ImageBorder">
-                    <Image x:Name="MainImage" Stretch="Uniform" Source="{Binding Pic}"  />
+                    <Image x:Name="MainImage"
+                           Stretch="Fill"
+                           Source="{Binding Pic}"
+                           Width="{Binding Width}"
+                           Height="{Binding Height}"/>
                 </Border>
                 </Border>
                 
                 
             </ScrollViewer>
             </ScrollViewer>