Просмотр исходного кода

Update for .NET 8, performance improvements, etc

Ruben 2 лет назад
Родитель
Сommit
af8b4f9a63

+ 11 - 1
src/PicView/ChangeImage/FastPic.cs

@@ -64,7 +64,17 @@ internal static class FastPic
             }
         }
 
-        await UpdateImage.UpdateImageValuesAsync(index, preLoadValue).ConfigureAwait(false);
+        _ = UpdateImage.UpdateImageValuesAsync(index, preLoadValue).ConfigureAwait(false);
+        if (UC.GetPicGallery is not null)
+        {
+            await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
+            {
+                // Select next item
+                GalleryNavigation.SetSelected(FolderIndex, true);
+                GalleryNavigation.SelectedGalleryItem = FolderIndex;
+                GalleryNavigation.ScrollToGalleryCenter();
+            });
+        }
 
         _updateSource = false;
         await PreLoader.PreLoadAsync(index, Pics.Count).ConfigureAwait(false);

+ 36 - 32
src/PicView/ChangeImage/FileHistory.cs

@@ -104,55 +104,59 @@ internal class FileHistory
             }
 
             SetTitle.SetLoadingString();
+            UC.GetSpinWaiter.Visibility = Visibility.Visible;
         }, DispatcherPriority.Normal);
 
-        if (Settings.Default.IncludeSubDirectories)
+        await Task.Run(async () => // Make sure UI responsive
         {
-            if (_fileHistory.Last().IsArchive())
+            if (Settings.Default.IncludeSubDirectories)
             {
-                await LoadPic.LoadPicFromArchiveAsync(_fileHistory.Last()).ConfigureAwait(false);
-                return;
-            }
-            var currentFolder = Path.GetDirectoryName(_fileHistory.Last());
-            var parentFolder = Path.GetDirectoryName(currentFolder);
-            var fileInfo = new FileInfo(parentFolder);
-            Navigation.Pics = await Task.FromResult(FileLists.FileList(fileInfo)).ConfigureAwait(false);
-            if (Navigation.Pics.Count > 0)
-            {
-                Navigation.FolderIndex = Navigation.Pics.IndexOf(_fileHistory.Last());
-                await LoadPic.LoadPicAtIndexAsync(Navigation.FolderIndex).ConfigureAwait(false);
-
-                // Fix if Bottom Gallery is enabled
-                if (Settings.Default.IsBottomGalleryShown)
+                if (_fileHistory.Last().IsArchive())
                 {
-                    if (UC.GetPicGallery is { Visibility: Visibility.Collapsed })
+                    await LoadPic.LoadPicFromArchiveAsync(_fileHistory.Last()).ConfigureAwait(false);
+                    return;
+                }
+                var currentFolder = Path.GetDirectoryName(_fileHistory.Last());
+                var parentFolder = Path.GetDirectoryName(currentFolder);
+                var fileInfo = new FileInfo(parentFolder);
+                Navigation.Pics = await Task.FromResult(FileLists.FileList(fileInfo)).ConfigureAwait(false);
+                if (Navigation.Pics.Count > 0)
+                {
+                    Navigation.FolderIndex = Navigation.Pics.IndexOf(_fileHistory.Last());
+                    await LoadPic.LoadPicAtIndexAsync(Navigation.FolderIndex).ConfigureAwait(false);
+
+                    // Fix if Bottom Gallery is enabled
+                    if (Settings.Default.IsBottomGalleryShown)
                     {
-                        var shouldLoadGallery = false;
-                        await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
+                        if (UC.GetPicGallery is { Visibility: Visibility.Collapsed })
                         {
-                            GalleryToggle.ShowBottomGallery();
-                            ScaleImage.TryFitImage();
-                            if (UC.GetPicGallery.Container.Children.Count <= 0)
+                            var shouldLoadGallery = false;
+                            await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
+                            {
+                                GalleryToggle.ShowBottomGallery();
+                                ScaleImage.TryFitImage();
+                                if (UC.GetPicGallery.Container.Children.Count <= 0)
+                                {
+                                    shouldLoadGallery = true;
+                                }
+                            });
+                            if (shouldLoadGallery)
                             {
-                                shouldLoadGallery = true;
+                                await GalleryLoad.LoadAsync().ConfigureAwait(false);
                             }
-                        });
-                        if (shouldLoadGallery)
-                        {
-                            await GalleryLoad.LoadAsync().ConfigureAwait(false);
                         }
                     }
                 }
+                else
+                {
+                    await LoadPic.LoadPicFromStringAsync(_fileHistory.Last()).ConfigureAwait(false);
+                }
             }
             else
             {
                 await LoadPic.LoadPicFromStringAsync(_fileHistory.Last()).ConfigureAwait(false);
             }
-        }
-        else
-        {
-            await LoadPic.LoadPicFromStringAsync(_fileHistory.Last()).ConfigureAwait(false);
-        }
+        });
     }
 
     internal void Add(string fileName)

+ 89 - 49
src/PicView/ChangeImage/LoadPic.cs

@@ -8,12 +8,16 @@ using System.Diagnostics;
 using System.IO;
 using System.Windows;
 using System.Windows.Threading;
+using PicView.UILogic.Sizing;
 using static PicView.ChangeImage.ErrorHandling;
 using static PicView.ChangeImage.Navigation;
 using static PicView.ChangeTitlebar.SetTitle;
 using static PicView.FileHandling.ArchiveExtraction;
 using static PicView.FileHandling.FileLists;
 using static PicView.UILogic.UC;
+using PicView.Views.UserControls.Gallery;
+using System.Windows.Media.Imaging;
+using ImageMagick;
 
 namespace PicView.ChangeImage;
 
@@ -31,67 +35,70 @@ internal static class LoadPic
     {
         await ConfigureWindows.GetMainWindow.Dispatcher.InvokeAsync(SetLoadingString);
 
-        if (fileInfo is not null)
+        await Task.Run(async () =>
         {
-            if (fileInfo.Exists)
+            if (fileInfo is not null)
             {
-                if (fileInfo.IsSupported())
+                if (fileInfo.Exists)
                 {
-                    await LoadPiFromFileAsync(null, fileInfo).ConfigureAwait(false);
+                    if (fileInfo.IsSupported())
+                    {
+                        await LoadPiFromFileAsync(null, fileInfo).ConfigureAwait(false);
+                    }
+                    else if (fileInfo.IsArchive())
+                    {
+                        await LoadPicFromArchiveAsync(path).ConfigureAwait(false);
+                    }
                 }
-                else if (fileInfo.IsArchive())
+                else if (path is not null && !string.IsNullOrWhiteSpace(path.GetURL()) ||
+                         !string.IsNullOrWhiteSpace(fileInfo.LinkTarget.GetURL()))
                 {
-                    await LoadPicFromArchiveAsync(path).ConfigureAwait(false);
+                    await HttpFunctions.LoadPicFromUrlAsync(path).ConfigureAwait(false);
+                }
+                else if (fileInfo.Attributes.HasFlag(FileAttributes.Directory))
+                {
+                    await LoadPicFromFolderAsync(fileInfo, 0).ConfigureAwait(false);
+                }
+                else
+                {
+                    await ReloadAsync().ConfigureAwait(false);
                 }
             }
-            else if (path is not null && !string.IsNullOrWhiteSpace(path.GetURL()) ||
-                     !string.IsNullOrWhiteSpace(fileInfo.LinkTarget.GetURL()))
-            {
-                await HttpFunctions.LoadPicFromUrlAsync(path).ConfigureAwait(false);
-            }
-            else if (fileInfo.Attributes.HasFlag(FileAttributes.Directory))
-            {
-                await LoadPicFromFolderAsync(fileInfo, 0).ConfigureAwait(false);
-            }
-            else
-            {
-                await ReloadAsync().ConfigureAwait(false);
-            }
-        }
-        else if (!string.IsNullOrWhiteSpace(path))
-        {
-            var check = CheckIfLoadableString(path);
-            switch (check)
+            else if (!string.IsNullOrWhiteSpace(path))
             {
-                default:
-                    await LoadPiFromFileAsync(check).ConfigureAwait(false);
-                    return;
+                var check = CheckIfLoadableString(path);
+                switch (check)
+                {
+                    default:
+                        await LoadPiFromFileAsync(check).ConfigureAwait(false);
+                        return;
 
-                case "web":
-                    await HttpFunctions.LoadPicFromUrlAsync(path).ConfigureAwait(false);
-                    return;
+                    case "web":
+                        await HttpFunctions.LoadPicFromUrlAsync(path).ConfigureAwait(false);
+                        return;
 
-                case "base64":
-                    await UpdateImage.UpdateImageFromBase64PicAsync(path).ConfigureAwait(false);
-                    return;
+                    case "base64":
+                        await UpdateImage.UpdateImageFromBase64PicAsync(path).ConfigureAwait(false);
+                        return;
 
-                case "directory":
-                    await LoadPicFromFolderAsync(path).ConfigureAwait(false);
-                    return;
+                    case "directory":
+                        await LoadPicFromFolderAsync(path).ConfigureAwait(false);
+                        return;
 
-                case "zip":
-                    await LoadPicFromArchiveAsync(path).ConfigureAwait(false);
-                    return;
+                    case "zip":
+                        await LoadPicFromArchiveAsync(path).ConfigureAwait(false);
+                        return;
 
-                case "":
-                    ConfigureWindows.GetMainWindow.Dispatcher.Invoke(DispatcherPriority.Render, () => Unload(true));
-                    return;
+                    case "":
+                        ConfigureWindows.GetMainWindow.Dispatcher.Invoke(DispatcherPriority.Render, () => Unload(true));
+                        return;
+                }
             }
-        }
-        else
-        {
-            await ReloadAsync().ConfigureAwait(false);
-        }
+            else
+            {
+                await ReloadAsync().ConfigureAwait(false);
+            }
+        });
     }
 
     #endregion Load Pic from String
@@ -385,7 +392,38 @@ internal static class LoadPic
         // display the loading preview and wait until the image is loaded.
         if (preLoadValue is null or { BitmapSource: null })
         {
-            var thumb = Thumbnails.GetThumb(FolderIndex, fileInfo);
+            using var image = new MagickImage();
+            image.Ping(fileInfo);
+            BitmapSource? thumb = null;
+            if (GetPicGallery != null)
+            {
+                var fromGallery = false;
+                await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
+                {
+                    if (GetPicGallery.Container.Children.Count > 0 && index < GetPicGallery.Container.Children.Count)
+                    {
+                        var y = GetPicGallery.Container.Children[index] as PicGalleryItem;
+                        thumb = (BitmapSource)y.ThumbImage.Source;
+                        fromGallery = true;
+                    }
+                });
+                if (!fromGallery)
+                {
+                    var exifThumbnail = image.GetExifProfile()?.CreateThumbnail();
+                    thumb = exifThumbnail?.ToBitmapSource();
+                }
+            }
+            else
+            {
+                var exifThumbnail = image.GetExifProfile()?.CreateThumbnail();
+                thumb = exifThumbnail?.ToBitmapSource();
+            }
+
+            if (index != FolderIndex)
+            {
+                await PreLoader.PreLoadAsync(index, Pics.Count).ConfigureAwait(false);
+                return; // Skip loading if user went to next value
+            }
 
             await ConfigureWindows.GetMainWindow.Dispatcher.InvokeAsync(() =>
             {
@@ -393,10 +431,12 @@ internal static class LoadPic
                 GetSpinWaiter.Visibility = Visibility.Visible;
 
                 ConfigureWindows.GetMainWindow.MainImage.Source = thumb;
+                if (image is { Height: > 0, Width: > 0 })
+                    ScaleImage.FitImage(image.Width, image.Height);
             }, DispatcherPriority.Send);
 
             // Update gallery selections
-            if (GetPicGallery is not null)
+            if (GetPicGallery is not null && index == FolderIndex)
             {
                 await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
                 {

+ 8 - 15
src/PicView/ChangeImage/Navigation.cs

@@ -123,24 +123,17 @@ internal static class Navigation
             });
         }
 
-        if (fastPic)
+        await Task.Run(async () =>
         {
-            await FastPic.Run(next).ConfigureAwait(false);
-            if (UC.GetPicGallery is not null)
+            if (fastPic)
             {
-                await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
-                {
-                    // Select next item
-                    GalleryNavigation.SetSelected(FolderIndex, true);
-                    GalleryNavigation.SelectedGalleryItem = FolderIndex;
-                    GalleryNavigation.ScrollToGalleryCenter();
-                });
+                await FastPic.Run(next).ConfigureAwait(false);
             }
-        }
-        else
-        {
-            await LoadPic.LoadPicAtIndexAsync(next).ConfigureAwait(false);
-        }
+            else
+            {
+                await LoadPic.LoadPicAtIndexAsync(next).ConfigureAwait(false);
+            }
+        });
     }
 
     /// <summary>

+ 15 - 8
src/PicView/ChangeImage/QuickLoad.cs

@@ -12,6 +12,7 @@ using System.Windows.Threading;
 using XamlAnimatedGif;
 using static PicView.ChangeImage.LoadPic;
 using static PicView.ChangeImage.Navigation;
+using static PicView.ChangeImage.PreLoader;
 using static PicView.ChangeTitlebar.SetTitle;
 using static PicView.FileHandling.ArchiveExtraction;
 using static PicView.FileHandling.FileLists;
@@ -43,18 +44,24 @@ internal static class QuickLoad
         var bitmapSource = await ImageDecoder.ReturnBitmapSourceAsync(fileInfo).ConfigureAwait(false);
         await mainWindow.MainImage.Dispatcher.InvokeAsync(() =>
         {
-            if (fileInfo.Extension.ToLowerInvariant() == ".gif")
-            {
-                AnimationBehavior.SetSourceUri(ConfigureWindows.GetMainWindow.MainImage, new Uri(fileInfo.FullName));
-            }
-            else
-            {
-                ConfigureWindows.GetMainWindow.MainImage.Source = bitmapSource;
-            }
+            ConfigureWindows.GetMainWindow.MainImage.Source = bitmapSource;
 
             FitImage(bitmapSource.Width, bitmapSource.Height);
         }, DispatcherPriority.Send);
 
+        if (fileInfo.Extension.Equals(".gif", StringComparison.OrdinalIgnoreCase))
+        {
+            var frames = ImageFunctions.GetImageFrames(fileInfo.FullName);
+            if (frames > 0)
+            {
+                var uri = new Uri(fileInfo.FullName);
+                await ConfigureWindows.GetMainWindow.Dispatcher.InvokeAsync(() =>
+                {
+                    AnimationBehavior.SetSourceUri(ConfigureWindows.GetMainWindow.MainImage, uri);
+                }, DispatcherPriority.Normal);
+            }
+        }
+
         Pics = await Task.FromResult(FileList(fileInfo)).ConfigureAwait(false);
         FolderIndex = Pics.IndexOf(fileInfo.FullName);
 

+ 9 - 4
src/PicView/ChangeImage/UpdateImage.cs

@@ -1,4 +1,5 @@
-using PicView.FileHandling;
+using System.IO;
+using PicView.FileHandling;
 using PicView.ImageHandling;
 using PicView.PicGallery;
 using PicView.Properties;
@@ -78,11 +79,15 @@ internal static class UpdateImage
 
         if (preLoadValue.FileInfo.Extension.Equals(".gif", StringComparison.OrdinalIgnoreCase))
         {
-            var frames = ImageFunctions.GetImageFrames(Pics[index]);
+            var frames = ImageFunctions.GetImageFrames(preLoadValue.FileInfo.FullName);
             if (frames > 0)
             {
-                var uri = new Uri(Pics[index]);
-                AnimationBehavior.SetSourceUri(ConfigureWindows.GetMainWindow.MainImage, uri);
+                var uri = new Uri(preLoadValue.FileInfo.FullName);
+                await ConfigureWindows.GetMainWindow.Dispatcher.InvokeAsync(() =>
+                {
+                    if (index == FolderIndex)
+                        AnimationBehavior.SetSourceUri(ConfigureWindows.GetMainWindow.MainImage, uri);
+                }, DispatcherPriority.Normal);
             }
         }
 

+ 10 - 50
src/PicView/ImageHandling/Thumbnails.cs

@@ -1,8 +1,7 @@
 using ImageMagick;
 using PicView.ChangeImage;
+using PicView.UILogic;
 using PicView.Views.UserControls.Gallery;
-using SkiaSharp;
-using SkiaSharp.Views.WPF;
 using System.Diagnostics;
 using System.IO;
 using System.Windows.Media.Imaging;
@@ -22,7 +21,7 @@ internal static class Thumbnails
         BitmapSource? pic;
         try
         {
-            if (GetPicGallery != null && GetPicGallery.Container.Children.Count > 0 && x < GetPicGallery.Container.Children.Count)
+            if (ConfigureWindows.GetMainWindow.CheckAccess() && GetPicGallery != null && GetPicGallery.Container.Children.Count > 0 && x < GetPicGallery.Container.Children.Count)
             {
                 var y = GetPicGallery.Container.Children[x] as PicGalleryItem;
                 pic = (BitmapSource)y.ThumbImage.Source;
@@ -61,7 +60,7 @@ internal static class Thumbnails
         return pic;
     }
 
-    internal static BitmapSource GetBitmapSourceThumb(string file, int size)
+    internal static BitmapSource GetBitmapSourceThumb(string file, int size, FileInfo? fileInfo = null)
     {
         try
         {
@@ -74,55 +73,16 @@ internal static class Thumbnails
                 bitmapThumb.Freeze();
                 return bitmapThumb;
             }
-        }
-        catch (Exception e)
-        {
-#if DEBUG
-            Trace.WriteLine(nameof(GetBitmapSourceThumb) + " " + e.Message);
-#endif
-        }
 
-        try
-        {
-            var fileInfo = new FileInfo(file);
-            var extension = fileInfo.Extension.ToLowerInvariant();
+            fileInfo ??= new FileInfo(file);
             var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferSize: 4096,
                 useAsync: fileInfo.Length > 1e+8);
-            switch (extension)
-            {
-                case ".jpg":
-                case ".jpeg":
-                case ".jpe":
-                case ".png":
-                case ".bmp":
-                case ".gif":
-                case ".jfif":
-                case ".ico":
-                case ".webp":
-                case ".wbmp":
-
-                    var sKBitmap = SKBitmap.Decode(fileStream);
-                    if (sKBitmap is null)
-                    {
-                        return ImageFunctions.ShowLogo() ?? ImageFunctions.ImageErrorMessage();
-                    }
-
-                    var skPic = sKBitmap.Resize(new SKImageInfo(size, size, SKColorType.Rgba8888), SKFilterQuality.High)
-                        .ToWriteableBitmap();
-                    sKBitmap.Dispose();
-                    fileStream.Dispose();
-                    skPic.Freeze();
-                    return skPic;
-
-                default:
-                    var image = new MagickImage();
-                    image.Read(fileStream);
-                    image.Thumbnail(new MagickGeometry(size, size));
-                    var bmp = image.ToBitmapSource();
-                    bmp?.Freeze();
-                    image.Dispose();
-                    return bmp ?? ImageFunctions.ShowLogo() ?? ImageFunctions.ImageErrorMessage();
-            }
+            image.Read(fileStream);
+            image.Thumbnail(new MagickGeometry(size, size));
+            var bmp = image.ToBitmapSource();
+            bmp?.Freeze();
+            image.Dispose();
+            return bmp ?? ImageFunctions.ShowLogo();
         }
         catch (Exception e)
         {

+ 36 - 40
src/PicView/PicGallery/GalleryLoad.cs

@@ -43,8 +43,8 @@ internal static class GalleryLoad
 
         internal static GalleryThumbHolder GetThumbData(int index)
         {
-            var bitmapSource = Thumbnails.GetBitmapSourceThumb(Navigation.Pics[index], (int)GalleryNavigation.PicGalleryItemSize);
             var fileInfo = new FileInfo(Navigation.Pics[index]);
+            var bitmapSource = Thumbnails.GetBitmapSourceThumb(Navigation.Pics[index], (int)GalleryNavigation.PicGalleryItemSize, fileInfo);
             var fileLocation = fileInfo.FullName;
             var fileName = Path.GetFileNameWithoutExtension(fileInfo.Name);
             var fileSize = $"{(string)Application.Current.Resources["FileSize"]}: {fileInfo.Length.GetReadableFileSize()}";
@@ -61,28 +61,44 @@ internal static class GalleryLoad
         var source = new CancellationTokenSource();
         var iterations = Navigation.Pics.Count;
 
-        for (int i = 0; i < iterations; i++)
+        async Task UpdateThumbAsync(int i, int updates)
         {
-            try
+            var galleryThumbHolderItem = await Task.FromResult(GalleryThumbHolder.GetThumbData(i)).ConfigureAwait(false);
+            await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
             {
-                if (iterations != Navigation.Pics.Count)
+                UpdatePic(i, galleryThumbHolderItem.BitmapSource, galleryThumbHolderItem.FileLocation,
+                    galleryThumbHolderItem.FileName, galleryThumbHolderItem.FileSize,
+                    galleryThumbHolderItem.FileDate);
+            }, DispatcherPriority.Background, source.Token);
+            if (updates == iterations)
+                IsLoading = false;
+        }
+
+        await Task.Run(async () =>
+        {
+            for (int i = 0; i < iterations; i++)
+            {
+                try
                 {
-                    await source.CancelAsync();
+                    if (iterations != Navigation.Pics.Count)
+                    {
+                        await source.CancelAsync();
+                        return;
+                    }
+
+                    var i1 = i;
+                    await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
+                    {
+                        Add(i1);
+                    }, DispatcherPriority.DataBind, source.Token);
                 }
-                await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
+                catch (Exception)
                 {
-                    Add(i);
-                }, DispatcherPriority.DataBind, source.Token);
-            }
-            catch (Exception)
-            {
-                GalleryFunctions.Clear();
-                return;
+                    GalleryFunctions.Clear();
+                    return;
+                }
             }
-        }
 
-        await Task.Run(async () =>
-        {
             var priority = iterations > 3000 ? DispatcherPriority.Background : DispatcherPriority.Render;
             var startPosition = 0;
             var updates = 0;
@@ -102,27 +118,16 @@ internal static class GalleryLoad
                     Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
                 }
 
-                await Parallel.ForAsync(startPosition, iterations, source.Token, async (x, loopState) =>
+                for (int i = startPosition; i < iterations; i++)
                 {
                     updates++;
                     try
                     {
-                        var i = x;
-
                         if (!IsLoading || Navigation.Pics.Count < Navigation.FolderIndex || Navigation.Pics.Count < 1 || i > Navigation.Pics.Count)
                         {
-                            loopState.ThrowIfCancellationRequested();
                             throw new TaskCanceledException();
                         }
-                        var galleryThumbHolderItem = GalleryThumbHolder.GetThumbData(i);
-                        await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
-                        {
-                            UpdatePic(i, galleryThumbHolderItem.BitmapSource, galleryThumbHolderItem.FileLocation,
-                                galleryThumbHolderItem.FileName, galleryThumbHolderItem.FileSize,
-                                galleryThumbHolderItem.FileDate);
-                        }, DispatcherPriority.Background, source.Token);
-                        if (updates == iterations)
-                            IsLoading = false;
+                        await UpdateThumbAsync(i, updates).ConfigureAwait(false);
                     }
                     catch (Exception e)
                     {
@@ -131,7 +136,7 @@ internal static class GalleryLoad
 #endif
                         IsLoading = false;
                     }
-                });
+                }
             }, source.Token).ConfigureAwait(false);
 
             _ = Task.Run(async () =>
@@ -151,16 +156,7 @@ internal static class GalleryLoad
                         {
                             throw new TaskCanceledException();
                         }
-
-                        var galleryThumbHolderItem = GalleryThumbHolder.GetThumbData(i);
-                        await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
-                        {
-                            UpdatePic(i, galleryThumbHolderItem.BitmapSource, galleryThumbHolderItem.FileLocation,
-                                galleryThumbHolderItem.FileName, galleryThumbHolderItem.FileSize,
-                                galleryThumbHolderItem.FileDate);
-                        }, DispatcherPriority.Background, source.Token);
-                        if (updates == iterations)
-                            IsLoading = false;
+                        await UpdateThumbAsync(i, updates).ConfigureAwait(false);
                     }
                     catch (Exception e)
                     {

+ 3 - 0
src/PicView/PicView.csproj

@@ -322,6 +322,9 @@
   <ItemGroup>
     <Resource Include="Themes\Resources\img\icon__Q6k_icon.ico" />
   </ItemGroup>
+	<ItemGroup>
+		<RuntimeHostConfigurationOption Include="Switch.System.Windows.Media.EnableHardwareAccelerationInRdp" Value="true" />
+	</ItemGroup>
 	
   <PropertyGroup>
     <FileVersion>1.9.6</FileVersion>

+ 0 - 1
src/PicView/Shortcuts/MainKeyboardShortcuts.cs

@@ -11,7 +11,6 @@ using PicView.UILogic;
 using PicView.UILogic.Sizing;
 using System.Windows;
 using System.Windows.Input;
-using System.Windows.Media;
 using static PicView.ChangeImage.ErrorHandling;
 using static PicView.ChangeImage.Navigation;
 using static PicView.FileHandling.CopyPaste;

+ 0 - 73
src/XamlAnimatedGif/AnimationBehavior.cs

@@ -131,29 +131,6 @@ public static class AnimationBehavior
 
     #endregion AutoStart
 
-    #region AnimateInDesignMode
-
-    public static bool GetAnimateInDesignMode(DependencyObject obj)
-    {
-        return (bool)obj.GetValue(AnimateInDesignModeProperty);
-    }
-
-    public static void SetAnimateInDesignMode(DependencyObject obj, bool value)
-    {
-        obj.SetValue(AnimateInDesignModeProperty, value);
-    }
-
-    public static readonly DependencyProperty AnimateInDesignModeProperty =
-        DependencyProperty.RegisterAttached(
-            "AnimateInDesignMode",
-            typeof(bool),
-            typeof(AnimationBehavior),
-            new PropertyMetadata(
-                false,
-                AnimateInDesignModeChanged));
-
-    #endregion AnimateInDesignMode
-
     #region Animator
 
     [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
@@ -319,44 +296,6 @@ public static class AnimationBehavior
         GetAnimator(o)?.OnRepeatBehaviorChanged();
     }
 
-    private static async void AnimateInDesignModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
-    {
-        if (d is not Image image)
-            return;
-
-        await InitAnimationAsync(image).ConfigureAwait(false);
-    }
-
-    private static bool CheckDesignMode(Image image, Uri sourceUri, Stream sourceStream)
-    {
-        if (IsInDesignMode(image) && !GetAnimateInDesignMode(image))
-        {
-            try
-            {
-                if (sourceStream != null)
-                {
-                    SetStaticImage(image, sourceStream);
-                }
-                else if (sourceUri != null)
-                {
-                    var bmp = new BitmapImage
-                    {
-                        UriSource = sourceUri
-                    };
-                    image.Source = bmp;
-                }
-            }
-            catch
-            {
-                image.Source = null;
-            }
-
-            return false;
-        }
-
-        return true;
-    }
-
     private static async Task InitAnimationAsync(Image image)
     {
         if (IsLoaded(image))
@@ -443,9 +382,6 @@ public static class AnimationBehavior
     private static async Task InitAnimationAsync(Image image, Uri sourceUri, RepeatBehavior repeatBehavior,
         int seqNum, bool cacheFrameDataInMemory)
     {
-        if (!CheckDesignMode(image, sourceUri, null))
-            return;
-
         try
         {
             var animator = await ImageAnimator.CreateAsync(sourceUri, repeatBehavior, null, image,
@@ -475,9 +411,6 @@ public static class AnimationBehavior
     private static async void InitAnimationAsync(Image image, Stream stream, RepeatBehavior repeatBehavior,
         int seqNum, bool cacheFrameDataInMemory)
     {
-        if (!CheckDesignMode(image, null, stream))
-            return;
-
         try
         {
             var animator = await ImageAnimator.CreateAsync(stream, repeatBehavior, image, cacheFrameDataInMemory);
@@ -533,12 +466,6 @@ public static class AnimationBehavior
         SetAnimator(image, null);
     }
 
-    // ReSharper disable once UnusedParameter.Local (used in WPF)
-    private static bool IsInDesignMode(DependencyObject obj)
-    {
-        return DesignerProperties.GetIsInDesignMode(obj);
-    }
-
     private static async Task SetStaticImageAsync(Image image, Uri sourceUri)
     {
         try

+ 4 - 0
src/XamlAnimatedGif/XamlAnimatedGif.csproj

@@ -18,10 +18,14 @@
     <PackageIcon>assets/xamlanimatedgif.png</PackageIcon>
     <SupportedOSPlatformVersion>10.0.22621.0</SupportedOSPlatformVersion>
     <ImplicitUsings>enable</ImplicitUsings>
+    <PlatformTarget>x64</PlatformTarget>
   </PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'net45'">
     <DefineConstants>$(DefineConstants);LACKS_STREAM_MEMORY_OVERLOADS</DefineConstants>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <DebugType>none</DebugType>
+  </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == 'net45'">
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />