From 4867d520133153ca12d283f83965baa99c5d2d88 Mon Sep 17 00:00:00 2001 From: ClemensFischer Date: Wed, 22 May 2024 16:15:29 +0200 Subject: [PATCH] Avalonia ImageLoader --- MapControl/Avalonia/ImageLoader.Avalonia.cs | 50 ++++++++++++++++--- .../Avalonia/MapControl.Avalonia.csproj | 1 + MapControl/Shared/ImageLoader.cs | 16 ++++++ MapControl/WPF/ImageLoader.WPF.cs | 24 +++------ MapControl/WinUI/ImageLoader.WinUI.cs | 14 +----- 5 files changed, 69 insertions(+), 36 deletions(-) diff --git a/MapControl/Avalonia/ImageLoader.Avalonia.cs b/MapControl/Avalonia/ImageLoader.Avalonia.cs index 0f0aa6cb..2f384513 100644 --- a/MapControl/Avalonia/ImageLoader.Avalonia.cs +++ b/MapControl/Avalonia/ImageLoader.Avalonia.cs @@ -4,6 +4,7 @@ using Avalonia.Media; using Avalonia.Media.Imaging; +using Avalonia.Platform; using System; using System.IO; using System.Threading.Tasks; @@ -29,22 +30,57 @@ namespace MapControl public static Task LoadImageAsync(string path) { + if (!File.Exists(path)) + { + return Task.FromResult(null); + } + return Task.Run(() => { - if (!File.Exists(path)) - { - return null; - } - using var stream = File.OpenRead(path); return LoadImage(stream); }); } - internal static Task LoadMergedImageAsync(Uri uri1, Uri uri2, IProgress progress) + internal static async Task LoadMergedImageAsync(Uri uri1, Uri uri2, IProgress progress) { - return Task.FromResult(null); + var images = await LoadImagesAsync(uri1, uri2, progress); + + WriteableBitmap image = null; + + if (images.Length == 2 && + images[0] is Bitmap image1 && + images[1] is Bitmap image2 && + image1.PixelSize.Height == image2.PixelSize.Height && + image1.Format.HasValue && + image2.Format.HasValue && + image1.Format.Value == image2.Format.Value && + image1.AlphaFormat.HasValue && + image2.AlphaFormat.HasValue && + image1.AlphaFormat.Value == image2.AlphaFormat.Value) + { + var bpp = image1.Format.Value == PixelFormat.Rgb565 ? 2 : 4; + var size = new PixelSize(image1.PixelSize.Width + image2.PixelSize.Width, image1.PixelSize.Height); + var stride1 = image1.PixelSize.Width * bpp; + var stride = size.Width * bpp; + var buffer = new byte[stride * size.Height]; + + unsafe + { + fixed (byte* ptr = buffer) + { + var p = (nint)ptr; + + image1.CopyPixels(new PixelRect(image1.PixelSize), p, buffer.Length, stride); + image2.CopyPixels(new PixelRect(image2.PixelSize), p + stride1, buffer.Length, stride); + + image = new WriteableBitmap(image1.Format.Value, image1.AlphaFormat.Value, p, size, image1.Dpi, stride); + } + } + } + + return image; } } } diff --git a/MapControl/Avalonia/MapControl.Avalonia.csproj b/MapControl/Avalonia/MapControl.Avalonia.csproj index ea0e446c..76bcfb3a 100644 --- a/MapControl/Avalonia/MapControl.Avalonia.csproj +++ b/MapControl/Avalonia/MapControl.Avalonia.csproj @@ -2,6 +2,7 @@ net8.0 disable + true MapControl XAML Map Control Library for Avalonia UI XAML Map Control diff --git a/MapControl/Shared/ImageLoader.cs b/MapControl/Shared/ImageLoader.cs index 7c0ed060..20bf5dc2 100644 --- a/MapControl/Shared/ImageLoader.cs +++ b/MapControl/Shared/ImageLoader.cs @@ -159,5 +159,21 @@ namespace MapControl return buffer; } + + private static Task LoadImagesAsync(Uri uri1, Uri uri2, IProgress progress) + { + IProgress progress1 = null; + IProgress progress2 = null; + + if (progress != null) + { + var p1 = 0d; + var p2 = 0d; + progress1 = new Progress(p => { p1 = p; progress.Report((p1 + p2) / 2d); }); + progress2 = new Progress(p => { p2 = p; progress.Report((p1 + p2) / 2d); }); + } + + return Task.WhenAll(LoadImageAsync(uri1, progress1), LoadImageAsync(uri2, progress2)); + } } } \ No newline at end of file diff --git a/MapControl/WPF/ImageLoader.WPF.cs b/MapControl/WPF/ImageLoader.WPF.cs index 851b0491..d94dc4e4 100644 --- a/MapControl/WPF/ImageLoader.WPF.cs +++ b/MapControl/WPF/ImageLoader.WPF.cs @@ -38,13 +38,13 @@ namespace MapControl public static Task LoadImageAsync(string path) { + if (!File.Exists(path)) + { + return Task.FromResult(null); + } + return Task.Run(() => { - if (!File.Exists(path)) - { - return null; - } - using (var stream = File.OpenRead(path)) { return LoadImage(stream); @@ -54,19 +54,9 @@ namespace MapControl internal static async Task LoadMergedImageAsync(Uri uri1, Uri uri2, IProgress progress) { + var images = await LoadImagesAsync(uri1, uri2, progress); + WriteableBitmap image = null; - IProgress progress1 = null; - IProgress progress2 = null; - - if (progress != null) - { - var p1 = 0d; - var p2 = 0d; - progress1 = new Progress(p => { p1 = p; progress.Report((p1 + p2) / 2d); }); - progress2 = new Progress(p => { p2 = p; progress.Report((p1 + p2) / 2d); }); - } - - var images = await Task.WhenAll(LoadImageAsync(uri1, progress1), LoadImageAsync(uri2, progress2)); if (images.Length == 2 && images[0] is BitmapSource image1 && diff --git a/MapControl/WinUI/ImageLoader.WinUI.cs b/MapControl/WinUI/ImageLoader.WinUI.cs index 66973940..b2055079 100644 --- a/MapControl/WinUI/ImageLoader.WinUI.cs +++ b/MapControl/WinUI/ImageLoader.WinUI.cs @@ -77,19 +77,9 @@ namespace MapControl internal static async Task LoadMergedImageAsync(Uri uri1, Uri uri2, IProgress progress) { + var images = await LoadImagesAsync(uri1, uri2, progress); + WriteableBitmap image = null; - IProgress progress1 = null; - IProgress progress2 = null; - - if (progress != null) - { - var p1 = 0d; - var p2 = 0d; - progress1 = new Progress(p => { p1 = p; progress.Report((p1 + p2) / 2d); }); - progress2 = new Progress(p => { p2 = p; progress.Report((p1 + p2) / 2d); }); - } - - var images = await Task.WhenAll(LoadImageAsync(uri1, progress1), LoadImageAsync(uri2, progress2)); if (images.Length == 2 && images[0] is WriteableBitmap image1 &&