diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_Image.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_Image.cs index f0790c63aaf4..ee9c568df3ce 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_Image.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_Image.cs @@ -13,6 +13,7 @@ using Windows.Foundation; using Windows.Foundation.Metadata; using Windows.Graphics.Display; +using Windows.Storage; using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -434,6 +435,19 @@ void Image_ImageOpened(object sender, RoutedEventArgs e) Assert.AreEqual("Image_ImageOpened", logs[1]); } + [TestMethod] + [RunsOnUIThread] + public async Task When_Loaded_From_AppData_LocalFolder() + { + var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/test_image_100_150.png")); + await file.CopyAsync(ApplicationData.Current.LocalFolder, "newfile.png", NameCollisionOption.ReplaceExisting); + var uri = new Uri($"ms-appdata:///Local/newfile.png"); + var bitmapImage = new BitmapImage(uri); + var image = new Image() { Source = bitmapImage }; + TestServices.WindowHelper.WindowContent = image; + await WindowHelper.WaitForLoaded(image); + } + private async Task TakeScreenshot(FrameworkElement SUT) { var renderer = new RenderTargetBitmap(); diff --git a/src/Uno.UI/UI/Xaml/Media/ImageSource.wasm.cs b/src/Uno.UI/UI/Xaml/Media/ImageSource.wasm.cs index f9eb202d6100..b437ac5a3a8f 100644 --- a/src/Uno.UI/UI/Xaml/Media/ImageSource.wasm.cs +++ b/src/Uno.UI/UI/Xaml/Media/ImageSource.wasm.cs @@ -1,11 +1,14 @@ #nullable enable -using Uno.Extensions; using System; +using System.IO; using System.Threading; using System.Threading.Tasks; -using Windows.Storage.Streams; +using Uno.Extensions; +using Uno.Helpers; using Uno.UI.Xaml.Media; +using Windows.Storage; +using Windows.Storage.Streams; #if !IS_UNO using Uno.Web.Query; @@ -57,5 +60,19 @@ internal virtual void ReportImageFailed(string errorMessage) } + internal virtual string? ContentType { get; } + + internal async Task OpenMsAppData(Uri uri, CancellationToken ct) + { + var file = await StorageFile.GetFileFromPathAsync(AppDataUriEvaluator.ToPath(uri)); + var stream = await file.OpenAsync(FileAccessMode.Read); + + var streamWithContentType = ContentType is { } contentType + ? stream.TrySetContentType(ContentType) + : stream.TrySetContentType(); + + return await OpenFromStream(streamWithContentType, null, ct); + } + } } diff --git a/src/Uno.UI/UI/Xaml/Media/Imaging/BitmapImage.wasm.cs b/src/Uno.UI/UI/Xaml/Media/Imaging/BitmapImage.wasm.cs index 612372f468a5..ead5c8e817df 100644 --- a/src/Uno.UI/UI/Xaml/Media/Imaging/BitmapImage.wasm.cs +++ b/src/Uno.UI/UI/Xaml/Media/Imaging/BitmapImage.wasm.cs @@ -24,7 +24,7 @@ public sealed partial class BitmapImage : BitmapSource { internal ResolutionScale? ScaleOverride { get; set; } - internal string ContentType { get; set; } = "application/octet-stream"; + internal override string ContentType { get; } = "application/octet-stream"; private protected override bool TryOpenSourceAsync( CancellationToken ct, @@ -43,7 +43,7 @@ private protected override bool TryOpenSourceAsync( _ => uri }; - asyncImage = AssetResolver.ResolveImageAsync(this, newUri, ScaleOverride); + asyncImage = AssetResolver.ResolveImageAsync(this, newUri, ScaleOverride, ct); return true; } @@ -91,7 +91,7 @@ private static async Task> GetAssets() return new HashSet(Regex.Split(assets, "\r\n|\r|\n")); } - internal static async Task ResolveImageAsync(ImageSource source, Uri uri, ResolutionScale? scaleOverride) + internal static async Task ResolveImageAsync(ImageSource source, Uri uri, ResolutionScale? scaleOverride, CancellationToken ct) { try { @@ -104,7 +104,11 @@ internal static async Task ResolveImageAsync(ImageSource source, Uri return ImageData.FromUrl(uri, source); } - // TODO: Implement ms-appdata + if (uri.IsAppData()) + { + return await source.OpenMsAppData(uri, ct); + } + return ImageData.Empty; } diff --git a/src/Uno.UI/UI/Xaml/Media/Imaging/SvgImageSource.wasm.cs b/src/Uno.UI/UI/Xaml/Media/Imaging/SvgImageSource.wasm.cs index bb7fb5b4b8d5..a23e2cee0a36 100644 --- a/src/Uno.UI/UI/Xaml/Media/Imaging/SvgImageSource.wasm.cs +++ b/src/Uno.UI/UI/Xaml/Media/Imaging/SvgImageSource.wasm.cs @@ -17,7 +17,7 @@ namespace Windows.UI.Xaml.Media.Imaging { partial class SvgImageSource { - internal string ContentType { get; set; } = "image/svg+xml"; + internal override string ContentType { get; } = "image/svg+xml"; partial void InitPartial() { @@ -88,16 +88,6 @@ private protected override bool TryOpenSourceAsync( return false; } - private protected async Task OpenMsAppData(Uri uri, CancellationToken ct) - { - var file = await StorageFile.GetFileFromPathAsync(AppDataUriEvaluator.ToPath(uri)); - var stream = await file.OpenAsync(FileAccessMode.Read); - - var streamWithContentType = stream.TrySetContentType(ContentType); - - return await OpenFromStream(streamWithContentType, null, ct); - } - internal override void ReportImageLoaded() => RaiseImageOpened(); internal override void ReportImageFailed(string errorMessage) => RaiseImageFailed(SvgImageSourceLoadStatus.Other);