WIP Image imports and file access
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.Avalonia;
|
||||
|
||||
|
||||
public class FileProvider(ITopLevelProvider topLevelProvider) :
|
||||
IFileProvider
|
||||
{
|
||||
public async Task<IReadOnlyCollection<string>> SelectFiles(FileFilter filter)
|
||||
{
|
||||
if (topLevelProvider.Get() is TopLevel topLevel)
|
||||
{
|
||||
IReadOnlyList<IStorageFile> storageFiles = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions()
|
||||
{
|
||||
AllowMultiple = filter.AllowMultiple,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
{
|
||||
new(filter.Name)
|
||||
{
|
||||
Patterns = filter.Extensions.Select(x => $"*.{x}").ToList()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return storageFiles.Select(file => file.Path.LocalPath).ToList();
|
||||
}
|
||||
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using Avalonia.Controls;
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.Avalonia;
|
||||
|
||||
public class FileSelector :
|
||||
IFileSelector
|
||||
{
|
||||
public async Task<IEnumerable<string>> SelectFiles(FileFilter filter)
|
||||
{
|
||||
//TopLevel topLevel = TopLevel.GetTopLevel(control);
|
||||
|
||||
//var openFileDialog = new OpenFileDialog();
|
||||
//openFileDialog.Filters.Add(new FileDialogFilter
|
||||
//{
|
||||
// Name = filter.Name,
|
||||
// Extensions = filter.Extensions
|
||||
//});
|
||||
|
||||
//openFileDialog.AllowMultiple = filter.AllowMultiple;
|
||||
|
||||
//var results = await openFileDialog.ShowAsync(window as Window);
|
||||
|
||||
//if (results != null && results.Length > 0)
|
||||
//{
|
||||
// return results.Select(result => result);
|
||||
//}
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using Avalonia.Media.Imaging;
|
||||
|
||||
namespace Toolkit.Avalonia;
|
||||
|
||||
public interface IImageResizer
|
||||
{
|
||||
public Bitmap Resize(Stream stream,
|
||||
int targetWidth,
|
||||
int targetHeight,
|
||||
bool maintainAspectRatio);
|
||||
}
|
||||
@@ -124,6 +124,11 @@ public static class IServiceCollectionExtensions
|
||||
|
||||
public static IServiceCollection AddAvalonia(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<ITopLevelProvider, TopLevelProvider>();
|
||||
services.AddTransient<IFileProvider, FileProvider>();
|
||||
services.AddTransient<IImageProvider, ImageProvider>();
|
||||
services.AddTransient<IImageResizer, ImageResizer>();
|
||||
|
||||
services.AddTransient<IDispatcher, AvaloniaDispatcher>();
|
||||
|
||||
services.AddTransient<IContentTemplate, ContentTemplate>();
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace Toolkit.Avalonia;
|
||||
|
||||
public interface ITopLevelProvider
|
||||
{
|
||||
TopLevel? Get();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Avalonia.Media.Imaging;
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.Avalonia;
|
||||
|
||||
public class ImageProvider(IImageResizer imageResizer) :
|
||||
IImageProvider
|
||||
{
|
||||
public async Task<IImageDescriptor> Get(string filePath,
|
||||
int width,
|
||||
int height,
|
||||
bool maintainAspectRatio)
|
||||
{
|
||||
await using FileStream stream = File.OpenRead(filePath);
|
||||
Bitmap resizedImage = imageResizer.Resize(stream, width, height, maintainAspectRatio);
|
||||
|
||||
return new ImageDescriptor(resizedImage, width, height);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using Avalonia.Media.Imaging;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Toolkit.Avalonia;
|
||||
|
||||
public class ImageResizer :
|
||||
IImageResizer
|
||||
{
|
||||
public Bitmap Resize(Stream stream,
|
||||
int targetWidth,
|
||||
int targetHeight,
|
||||
bool maintainAspectRatio)
|
||||
{
|
||||
using SKBitmap original = SKBitmap.Decode(stream);
|
||||
|
||||
float widthRatio = (float)targetWidth / original.Width;
|
||||
float heightRatio = (float)targetHeight / original.Height;
|
||||
float scale = maintainAspectRatio ? Math.Max(widthRatio, heightRatio) : Math.Min(widthRatio, heightRatio);
|
||||
|
||||
int newWidth = (int)(original.Width * scale);
|
||||
int newHeight = (int)(original.Height * scale);
|
||||
|
||||
using SKBitmap resized = new(newWidth, newHeight);
|
||||
using SKCanvas canvas = new(resized);
|
||||
|
||||
canvas.Clear(SKColors.Transparent);
|
||||
canvas.DrawBitmap(original, new SKRect(0, 0, newWidth, newHeight));
|
||||
|
||||
SKBitmap cropped;
|
||||
if (maintainAspectRatio)
|
||||
{
|
||||
int cropX = (newWidth - targetWidth) / 2;
|
||||
int cropY = (newHeight - targetHeight) / 2;
|
||||
|
||||
cropped = new SKBitmap(targetWidth, targetHeight);
|
||||
using SKCanvas croppedCanvas = new(cropped);
|
||||
SKRect cropRect = new(cropX, cropY, cropX + targetWidth, cropY + targetHeight);
|
||||
croppedCanvas.Clear(SKColors.Transparent);
|
||||
croppedCanvas.DrawBitmap(resized, cropRect, new SKRect(0, 0, targetWidth, targetHeight));
|
||||
}
|
||||
else
|
||||
{
|
||||
cropped = resized;
|
||||
}
|
||||
|
||||
using SKImage image = SKImage.FromBitmap(cropped);
|
||||
using MemoryStream outputStream = new();
|
||||
image.Encode(SKEncodedImageFormat.Png, 100).SaveTo(outputStream);
|
||||
outputStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
return new Bitmap(outputStream);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
|
||||
namespace Toolkit.Avalonia;
|
||||
|
||||
public class TopLevelProvider :
|
||||
ITopLevelProvider
|
||||
{
|
||||
public TopLevel? Get()
|
||||
{
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime classicDesktopStyleApplication)
|
||||
{
|
||||
if (TopLevel.GetTopLevel(classicDesktopStyleApplication.MainWindow) is TopLevel topLevel)
|
||||
{
|
||||
return topLevel;
|
||||
}
|
||||
}
|
||||
|
||||
if (Application.Current?.ApplicationLifetime is ISingleViewApplicationLifetime singleViewApplication)
|
||||
{
|
||||
if (TopLevel.GetTopLevel(singleViewApplication.MainView) is TopLevel topLevel)
|
||||
{
|
||||
return topLevel;
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
public record Activated
|
||||
{
|
||||
|
||||
@@ -7,4 +7,4 @@ public record Delete
|
||||
|
||||
public static DeleteEventArgs<TSender> As<TSender>() where TSender : new() =>
|
||||
new(new TSender());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
public interface IFileProvider
|
||||
{
|
||||
Task<IReadOnlyCollection<string>> SelectFiles(FileFilter filter);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
public interface IFileSelector
|
||||
{
|
||||
Task<IEnumerable<string>> SelectFiles(FileFilter filter);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public static class IHostBuilderExtension
|
||||
IFileInfo? fileInfo = null;
|
||||
if (provider.GetService<IHostEnvironment>() is IHostEnvironment hostEnvironment)
|
||||
{
|
||||
IFileProvider fileProvider = hostEnvironment.ContentRootFileProvider;
|
||||
Microsoft.Extensions.FileProviders.IFileProvider fileProvider = hostEnvironment.ContentRootFileProvider;
|
||||
fileInfo = fileProvider.GetFileInfo(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
public interface IImageDescriptor
|
||||
{
|
||||
public object Image { get; }
|
||||
|
||||
public int Width { get; }
|
||||
|
||||
public int Height { get; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
public interface IImageProvider
|
||||
{
|
||||
Task<IImageDescriptor> Get(string filePath,
|
||||
int width,
|
||||
int height,
|
||||
bool maintainAspectRatio = false);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
public record ImageDescriptor(object Image, int Width, int Height) :
|
||||
IImageDescriptor;
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
public record RequestEventArgs<TValue>(TValue? Value = default);
|
||||
public record RequestEventArgs<TSender>(TSender? Sender = default);
|
||||
|
||||
Reference in New Issue
Block a user