Completely removed GDI
Some checks failed
Build Windows Avalonia / build (push) Failing after 1m47s

This commit is contained in:
Maddo 2026-05-28 20:27:05 +02:00
commit d76e133f18
31 changed files with 236 additions and 2592 deletions

View file

@ -38,12 +38,6 @@
<TextBlock Text="Chunk:" VerticalAlignment="Center" Grid.Column="2" />
<TextBox Text="{Binding ChunkSize, Mode=TwoWay}" Width="74" Grid.Column="3" />
</Grid>
<TextBlock Text="Libreria Immagini" FontWeight="Bold" />
<StackPanel Margin="0,2,0,0" Spacing="3">
<RadioButton Content="System.Graphics" IsChecked="{Binding UseSystemGraphics}" GroupName="Lib" IsVisible="{Binding IsRunningOnWindows}" />
<RadioButton Content="ImageSharp" IsChecked="{Binding UseImageSharp}" GroupName="Lib" />
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="1" Spacing="8">

View file

@ -6,12 +6,8 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
#if WINDOWS
using System.Drawing.Text;
#endif
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Globalization;
using System.Threading;
@ -23,6 +19,7 @@ using AutoMapper;
using MaddoShared;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using SixLabors.Fonts;
namespace ImageCatalog_2
{
@ -561,16 +558,19 @@ namespace ImageCatalog_2
private List<string> LoadAvailableFonts()
{
#if WINDOWS
var fonts = new List<string>();
using (var installedFonts = new InstalledFontCollection())
try
{
fonts.AddRange(installedFonts.Families.Select(f => f.Name));
return SystemFonts.Collection.Families
.Select(f => f.Name)
.Where(name => !string.IsNullOrWhiteSpace(name))
.Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(name => name, StringComparer.CurrentCultureIgnoreCase)
.ToList();
}
catch
{
return new List<string>();
}
return fonts;
#else
return new List<string>();
#endif
}
private CancellationTokenSource? _mainToken;
@ -841,56 +841,6 @@ namespace ImageCatalog_2
set => _visual.LogoTransparency = value;
}
// Image library selection (UI radio buttons bind to the boolean helpers)
private string _imageLibrary = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "System.Graphics" : "ImageSharp";
/// <summary>
/// Whether the application is running on Windows. Used by cross-platform UIs to show/hide Windows-only options.
/// </summary>
public bool IsRunningOnWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
/// <summary>
/// The selected image processing library. Possible values: "System.Graphics" or "ImageSharp".
/// This value is mirrored into PicSettings.ImageCreatorProvider so the runtime mapper picks the implementation.
/// </summary>
public string ImageLibrary
{
get => _imageLibrary;
set
{
if (_imageLibrary == value) return;
_imageLibrary = value;
// Reflect selection into PicSettings so mapper can resolve at runtime
_picSettings.ImageCreatorProvider = string.Equals(value, "ImageSharp", StringComparison.OrdinalIgnoreCase)
? "ALTERNATE"
: "Sharp";
NotifyPropertyChanged();
NotifyPropertyChanged(nameof(UseSystemGraphics));
NotifyPropertyChanged(nameof(UseImageSharp));
NotifyPropertyChanged(nameof(IsRunningOnWindows));
}
}
public bool UseSystemGraphics
{
get => string.Equals(ImageLibrary, "System.Graphics", StringComparison.OrdinalIgnoreCase);
set
{
if (value) ImageLibrary = "System.Graphics";
NotifyPropertyChanged();
}
}
public bool UseImageSharp
{
get => string.Equals(ImageLibrary, "ImageSharp", StringComparison.OrdinalIgnoreCase);
set
{
if (value) ImageLibrary = "ImageSharp";
NotifyPropertyChanged();
}
}
// Folder division settings
private int _filesPerFolder = 99;
public int FilesPerFolder

File diff suppressed because it is too large Load diff

View file

@ -72,6 +72,7 @@
<PackageReference Include="AIFotoONLUS.Core" Version="0.1.2" Condition="'$(UseLocalAIFotoONLUS)' != 'true'" />
<PackageReference Include="AutoMapper" Version="16.1.1" />
<PackageReference Include="IconPacks.Avalonia" Version="2.0.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.8" />

View file

@ -1,6 +1,7 @@
using System.Drawing;
using AutoMapper;
using AutoMapper;
using MaddoShared;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
namespace ImageCatalog_2.Mappings;
@ -15,7 +16,7 @@ public class DataModelMappingProfile : Profile
// Paths
.ForMember(dest => dest.DirectorySorgente, opt => opt.MapFrom(src => src.SourcePath))
.ForMember(dest => dest.DirectoryDestinazione, opt => opt.MapFrom(src => src.DestinationPath))
// Font and text settings
.ForMember(dest => dest.DimStandard, opt => opt.MapFrom(src => src.FontSize))
.ForMember(dest => dest.DimStandardMiniatura, opt => opt.MapFrom(src => src.FontSizeThumbnail))
@ -25,8 +26,8 @@ public class DataModelMappingProfile : Profile
.ForMember(dest => dest.Allineamento, opt => opt.MapFrom(src => src.HorizontalAlignment))
.ForMember(dest => dest.Trasparenza, opt => opt.MapFrom(src => src.TextTransparency))
.ForMember(dest => dest.Margine, opt => opt.MapFrom(src => src.TextMargin))
.ForMember(dest => dest.FontColoreRGB, opt => opt.MapFrom(src => ColorTranslator.FromHtml(src.TextColorRGB)))
.ForMember(dest => dest.FontColoreRGB, opt => opt.MapFrom(src => ParseColor(src.TextColorRGB)))
// Thumbnail settings
.ForMember(dest => dest.AltezzaSmall, opt => opt.MapFrom(src => src.ThumbnailHeight))
.ForMember(dest => dest.LarghezzaSmall, opt => opt.MapFrom(src => src.ThumbnailWidth))
@ -34,14 +35,14 @@ public class DataModelMappingProfile : Profile
.ForMember(dest => dest.CreaMiniature, opt => opt.MapFrom(src => src.CreateThumbnails))
.ForMember(dest => dest.JpegQualityMin, opt => opt.MapFrom(src => src.JpegQualityThumbnail))
.ForMember(dest => dest.DimMin, opt => opt.MapFrom(src => src.FontSizeThumbnail))
// Big photo settings
.ForMember(dest => dest.AltezzaBig, opt => opt.MapFrom(src => src.PhotoBigHeight))
.ForMember(dest => dest.LarghezzaBig, opt => opt.MapFrom(src => src.PhotoBigWidth))
.ForMember(dest => dest.FotoGrandeDimOrigina, opt => opt.MapFrom(src => src.KeepOriginalDimensions))
.ForMember(dest => dest.JpegQuality, opt => opt.MapFrom(src => src.JpegQuality))
.ForMember(dest => dest.Codice, opt => opt.MapFrom(src => src.BigPhotoSuffix))
// Logo settings
.ForMember(dest => dest.LogoAggiungi, opt => opt.MapFrom(src => src.AddLogo))
.ForMember(dest => dest.LogoNomeFile, opt => opt.MapFrom(src => src.LogoFile))
@ -51,15 +52,15 @@ public class DataModelMappingProfile : Profile
.ForMember(dest => dest.LogoTrasparenza, opt => opt.MapFrom(src => src.LogoTransparency.ToString()))
.ForMember(dest => dest.LogoPosizioneH, opt => opt.MapFrom(src => src.LogoHorizontalPosition))
.ForMember(dest => dest.LogoPosizioneV, opt => opt.MapFrom(src => src.LogoVerticalPosition))
// Text content
.ForMember(dest => dest.TestoFirmaStart, opt => opt.MapFrom(src => src.HorizontalText))
.ForMember(dest => dest.TestoFirmaStartV, opt => opt.MapFrom(src => src.VerticalText))
// Vertical text settings
.ForMember(dest => dest.DimVert, opt => opt.MapFrom(src => src.VerticalTextSize))
.ForMember(dest => dest.MargVert, opt => opt.MapFrom(src => src.VerticalTextMargin))
// Boolean flags
.ForMember(dest => dest.UsaRotazioneAutomatica, opt => opt.MapFrom(src => src.AutomaticRotation))
.ForMember(dest => dest.UsaForzaJpg, opt => opt.MapFrom(src => src.ForceJpeg))
@ -68,18 +69,18 @@ public class DataModelMappingProfile : Profile
.ForMember(dest => dest.UsaOrarioTestoApplicare, opt => opt.MapFrom(src => src.AddTime))
.ForMember(dest => dest.UsaTempoGaraTestoApplicare, opt => opt.MapFrom(src => src.AddRaceTime))
.ForMember(dest => dest.OverwriteFiles, opt => opt.MapFrom(src => src.OverwriteImages))
// Additional settings
.ForMember(dest => dest.UsaOrarioMiniatura, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.Time))
.ForMember(dest => dest.DataPartenza, opt => opt.MapFrom(src => src.RaceStartDate))
.ForMember(dest => dest.TestoOrario, opt => opt.MapFrom(src => src.TimeLabel))
.ForMember(dest => dest.TestoMin, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.FileName))
// Thumbnail text options
.ForMember(dest => dest.AggiungiScritteMiniature, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.Text))
.ForMember(dest => dest.AggTempoGaraMin, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.RaceTime))
.ForMember(dest => dest.AggNumTempMin, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.FileNameAndTime))
// Ignore unmapped properties
.ForMember(dest => dest.DestDir, opt => opt.Ignore())
.ForMember(dest => dest.SecretDefault, opt => opt.Ignore())
@ -91,4 +92,27 @@ public class DataModelMappingProfile : Profile
.ForMember(dest => dest.FotoRuotaASinistra, opt => opt.Ignore())
.ForMember(dest => dest.TempMinText, opt => opt.Ignore());
}
private static Rgba32 ParseColor(string? value)
{
if (string.IsNullOrWhiteSpace(value))
{
return new Rgba32(255, 255, 0, 255);
}
try
{
var normalized = value.Trim();
if (normalized.Length == 6 && normalized.All(Uri.IsHexDigit))
{
normalized = "#" + normalized;
}
return Color.Parse(normalized).ToPixel<Rgba32>();
}
catch
{
return new Rgba32(255, 255, 0, 255);
}
}
}

View file

@ -192,11 +192,6 @@ namespace ImageCatalog_2.Models
[XmlElement("UsaColoreTrasparente")]
public bool UseTransparentColor { get; set; } = false;
// Selected image processing library (e.g., "System.Graphics" or "ImageSharp")
[JsonPropertyName("ImageLibrary")]
[XmlElement("ImageLibrary")]
public string ImageLibrary { get; set; } = "ImageSharp";
// Options
[JsonPropertyName("ForceJpeg")]
[XmlElement("GeneraleForzaJpg")]

View file

@ -143,13 +143,7 @@ static class Program
services.AddTransient<IAiExtractionService, AiExtractionService>();
services.AddTransient<IImageProcessingCoordinator, ImageProcessingCoordinator>();
services.AddTransient<ImageCreationService>();
#if WINDOWS
services.AddTransient<ImageCreatorGDI>();
#endif
services.AddTransient<ImageCreatorImageSharp>();
services.AddTransient<ImageCreatorMapper>();
services.AddTransient<IImageCreator>(sp => sp.GetRequiredService<ImageCreatorMapper>());
services.AddTransient<IImageCreator, ImageCreatorImageSharp>();
var userPrefsPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"ImageCatalog", "userprefs.xml");