using System; using System.IO; using Avalonia; using Avalonia.Logging; using Avalonia.Media; using Avalonia.Media.Imaging; using Avalonia.Threading; using DownKyi.Core.Storage; using DownKyi.CustomControl.AsyncImageLoader.Loaders; namespace DownKyi.CustomControl.AsyncImageLoader; public static class ImageBrushLoader { private static readonly ParametrizedLogger? Logger; public static IAsyncImageLoader AsyncImageLoader { get; set; } = new DiskCachedWebImageLoader(Path.Combine(StorageManager.GetCache(), "Images")); static ImageBrushLoader() { SourceProperty.Changed.AddClassHandler(OnSourceChanged); Logger = Avalonia.Logging.Logger.TryGet(LogEventLevel.Error, ImageLoader.AsyncImageLoaderLogArea); } private static async void OnSourceChanged(ImageBrush imageBrush, AvaloniaPropertyChangedEventArgs args) { var (oldValue, newValue) = args.GetOldAndNewValue(); if (oldValue == newValue) return; SetIsLoading(imageBrush, true); Bitmap? bitmap = null; try { if (newValue is not null) { // 注意缩放比例 var width = GetWidth(imageBrush); var height = GetHeight(imageBrush); if (width > 0 && height > 0) { var scale = await Dispatcher.UIThread.InvokeAsync(() => App.Current.MainWindow.DesktopScaling); var actualWidth = Convert.ToInt32(width * scale); var actualHeight = Convert.ToInt32(height * scale); bitmap = (await AsyncImageLoader.ProvideImageAsync(newValue))?.CreateScaledBitmap(new PixelSize(actualWidth, actualHeight)); } else { bitmap = await AsyncImageLoader.ProvideImageAsync(newValue); } } } catch (Exception e) { Logger?.Log("ImageBrushLoader", "ImageBrushLoader image resolution failed: {0}", e); } if (GetSource(imageBrush) != newValue) return; imageBrush.Source = bitmap; SetIsLoading(imageBrush, false); } public static readonly AttachedProperty SourceProperty = AvaloniaProperty.RegisterAttached("Source", typeof(ImageLoader)); public static string? GetSource(ImageBrush element) { return element.GetValue(SourceProperty); } public static void SetSource(ImageBrush element, string? value) { element.SetValue(SourceProperty, value); } public static readonly AttachedProperty IsLoadingProperty = AvaloniaProperty.RegisterAttached("IsLoading", typeof(ImageLoader)); public static bool GetIsLoading(ImageBrush element) { return element.GetValue(IsLoadingProperty); } private static void SetIsLoading(ImageBrush element, bool value) { element.SetValue(IsLoadingProperty, value); } public static readonly AttachedProperty WidthProperty = AvaloniaProperty.RegisterAttached("Width", typeof(ImageLoader)); public static int GetWidth(ImageBrush element) { return element.GetValue(WidthProperty); } public static void SetWidth(ImageBrush element, int value) { element.SetValue(WidthProperty, value); } public static readonly AttachedProperty HeightProperty = AvaloniaProperty.RegisterAttached("Height", typeof(ImageLoader)); public static int GetHeight(ImageBrush element) { return element.GetValue(HeightProperty); } public static void SetHeight(ImageBrush element, int value) { element.SetValue(HeightProperty, value); } }