Cross-platform: remove System.Drawing deps, add #if WINDOWS

Refactored image creation APIs to use byte[] for logo data instead of System.Drawing.Image, enabling cross-platform support. Wrapped all GDI+/Windows-specific code in #if WINDOWS and updated project files to conditionally include Windows-only dependencies. Defaulted to ImageSharp on non-Windows, and updated UI and settings to reflect platform capabilities. Application now builds and runs on Linux/macOS with Avalonia and ImageSharp, while retaining full Windows functionality.
This commit is contained in:
MaddoScientisto 2026-02-26 19:17:23 +01:00
commit 73597689ed
16 changed files with 115 additions and 90 deletions

View file

@ -7,6 +7,7 @@ namespace MaddoShared;
/// <summary>
/// Dynamically resolves the concrete IImageCreator implementation at call time
/// based on current PicSettings.ImageCreatorProvider.
/// On non-Windows platforms only ImageCreatorImageSharp is available.
/// </summary>
public class ImageCreatorMapper : IImageCreator
{
@ -21,29 +22,33 @@ public class ImageCreatorMapper : IImageCreator
_logger = logger;
}
public Task CreateImageAsync(ImageState imgState, System.Drawing.Image logo)
public Task CreateImageAsync(ImageState imgState, byte[]? logoData)
{
var provider = (_settings.ImageCreatorProvider ?? "Sharp").Trim();
_logger?.LogDebug("Resolving IImageCreator for provider '{Provider}'", provider);
#if WINDOWS
return provider.Equals("ALTERNATE", StringComparison.OrdinalIgnoreCase)
? ResolveAndCall<ImageCreatorImageSharp>(imgState, logo)
: ResolveAndCall<ImageCreatorGDI>(imgState, logo);
? ResolveAndCall<ImageCreatorImageSharp>(imgState, logoData)
: ResolveAndCall<ImageCreatorGDI>(imgState, logoData);
#else
// GDI is not available on non-Windows — always use ImageSharp
return ResolveAndCall<ImageCreatorImageSharp>(imgState, logoData);
#endif
}
private Task ResolveAndCall<T>(ImageState imgState, System.Drawing.Image logo) where T : IImageCreator
private Task ResolveAndCall<T>(ImageState imgState, byte[]? logoData) where T : IImageCreator
{
// Resolve the concrete implementation and forward the call
var impl = (IImageCreator)_sp.GetService(typeof(T));
var impl = (IImageCreator?)_sp.GetService(typeof(T));
if (impl is null)
{
_logger?.LogWarning("Requested image creator {Type} is not registered. Falling back to ImageCreatorGDI.", typeof(T).Name);
impl = (IImageCreator)_sp.GetService(typeof(ImageCreatorGDI));
_logger?.LogWarning("Requested image creator {Type} is not registered. Falling back to ImageCreatorImageSharp.", typeof(T).Name);
impl = (IImageCreator?)_sp.GetService(typeof(ImageCreatorImageSharp));
}
if (impl is null)
throw new InvalidOperationException("No IImageCreator implementation is registered.");
return impl.CreateImageAsync(imgState, logo);
return impl.CreateImageAsync(imgState, logoData);
}
}