From 68c1106f65cf9b44e40615453d458636499a1d7d Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Tue, 10 Feb 2026 21:18:46 +0100 Subject: [PATCH] Enhance image processing performance and flexibility by introducing atomic counters, improving file pattern matching, and refining logo positioning logic. --- MaddoShared.Tests/MaddoShared.Tests.csproj | 18 +--- MaddoShared/FileHelperSharp.cs | 23 ++++- MaddoShared/ImageCreationStuff.cs | 17 +++- MaddoShared/ImageCreatorSharp.cs | 105 ++++++++++++++------- MaddoShared/MaddoShared.csproj | 5 +- MaddoShared/PicSettings.cs | 7 +- imagecatalog/DataModel.cs | 25 +++-- imagecatalog/ImageCatalog 2.csproj | 2 +- 8 files changed, 134 insertions(+), 68 deletions(-) diff --git a/MaddoShared.Tests/MaddoShared.Tests.csproj b/MaddoShared.Tests/MaddoShared.Tests.csproj index 5ab4340..ffb84db 100644 --- a/MaddoShared.Tests/MaddoShared.Tests.csproj +++ b/MaddoShared.Tests/MaddoShared.Tests.csproj @@ -9,26 +9,14 @@ - + - - + + - - - - - - - - - - - - diff --git a/MaddoShared/FileHelperSharp.cs b/MaddoShared/FileHelperSharp.cs index 905999e..ef15e32 100644 --- a/MaddoShared/FileHelperSharp.cs +++ b/MaddoShared/FileHelperSharp.cs @@ -88,7 +88,28 @@ namespace MaddoShared DirectoryInfo destDir; destDir = new DirectoryInfo(Path.Combine(dirDest.FullName)); - foreach (FileInfo file in dir.GetFiles(filter)) + + // Support multiple patterns separated by ';' or ',' + var patterns = (filter ?? "*").Split(new[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToArray(); + + // Collect matching files for all patterns and avoid duplicates + var matchedFiles = new List(); + foreach (var pat in patterns) + { + try + { + matchedFiles.AddRange(dir.GetFiles(pat)); + } + catch + { + // Ignore pattern errors and continue + } + } + + // Remove duplicates (by FullName) + var distinctFiles = matchedFiles.GroupBy(f => f.FullName, StringComparer.OrdinalIgnoreCase).Select(g => g.First()).OrderBy(f => f.Name).ToList(); + + foreach (FileInfo file in distinctFiles) { contaFilePerDir += 1; diff --git a/MaddoShared/ImageCreationStuff.cs b/MaddoShared/ImageCreationStuff.cs index 778a7e8..04f283a 100644 --- a/MaddoShared/ImageCreationStuff.cs +++ b/MaddoShared/ImageCreationStuff.cs @@ -142,13 +142,17 @@ namespace MaddoShared private List GetFilesToProcess(Options options) { + // Support multiple common JPEG patterns so files named .jpeg, .jpe, etc. are included + var jpgPatterns = new[] { "*.jpg", "*.jpeg", "*.jpe", "*.jfif", "*.pjpeg", "*.pjp" }; + if (options.AggiornaSottodirectory && options.CreaSottocartelle) { var helper = new FileHelperSharp(); + // Pass patterns joined by ';' - FileHelperSharp will split and handle multiple patterns return helper.GetFilesRecursive( new DirectoryInfo(options.SourcePath), new DirectoryInfo(options.DestinationPath), - "*.jpg", + string.Join(";", jpgPatterns), new FileHelperOptions { FilesPerFolder = options.FilePerCartella, @@ -158,10 +162,13 @@ namespace MaddoShared }); } - var files = Directory.EnumerateFiles( - options.SourcePath, - "*.jpg", - options.AggiornaSottodirectory ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); + // For non-recursive or recursive enumeration without using the helper, enumerate for each pattern + var searchOption = options.AggiornaSottodirectory ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + + var files = jpgPatterns + .SelectMany(p => Directory.EnumerateFiles(options.SourcePath, p, searchOption)) + .Distinct() + .ToList(); return files.Select(x => { diff --git a/MaddoShared/ImageCreatorSharp.cs b/MaddoShared/ImageCreatorSharp.cs index 0f77df9..e0edfb0 100644 --- a/MaddoShared/ImageCreatorSharp.cs +++ b/MaddoShared/ImageCreatorSharp.cs @@ -267,26 +267,36 @@ public class ImageCreatorSharp(PicSettings picSettings, ILogger image.Width * 0.95f || textSize.Height > maxTextHeight) && tempFontSize > 5) + { + tempFontSize = (tempFontSize > 20) ? tempFontSize - 5 : tempFontSize - 1; + using var tempFont = CreateFont(picSettings.IlFont, tempFontSize, picSettings.Grassetto); + textSize = graphics.MeasureString(imgState.TestoFirmaPiccola, tempFont); + } - SetVerticalPosition(image.Height, textSize.Height, imgState); + // Re-measure text with the final font size for accurate positioning + using var finalFont = CreateFont(picSettings.IlFont, tempFontSize, picSettings.Grassetto); + var finalTextSize = graphics.MeasureString(imgState.TestoFirmaPiccola, finalFont); - float xCenter = CalculateHorizontalAlignment(image.Width, textSize.Width); + SetVerticalPosition(image.Height, finalTextSize.Height, imgState); + + float xCenter = CalculateHorizontalAlignment(image.Width, finalTextSize.Width); using var stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; using var shadowBrush = new SolidBrush(Color.FromArgb(imgState.AlphaScelta, 0, 0, 0)); using var textBrush = new SolidBrush(Color.FromArgb(imgState.AlphaScelta, picSettings.FontColoreRGB)); - imgState.DimensioneStandardMiniatura = picSettings.DimMin; - - using var finalFont = - CreateFont(picSettings.IlFont, imgState.DimensioneStandardMiniatura, picSettings.Grassetto); DrawText(graphics, imgState, xCenter, stringFormat, shadowBrush, textBrush, finalFont); using var finalThumb = @@ -324,20 +334,6 @@ public class ImageCreatorSharp(PicSettings picSettings, ILogger maxWidth && currentSize > 5) - { - currentSize = (currentSize > 20) ? currentSize - 5 : currentSize - 1; - using var tempFont = CreateFont(picSettings.IlFont, currentSize, picSettings.Grassetto); - size = g.MeasureString(imgState.TestoFirmaPiccola, tempFont); - //tempFont.Dispose(); - } - - imgState.DimensioneStandardMiniatura = currentSize; - } private void AddText(Image g, ImageState imgState, Bitmap imgOutputBig) { @@ -493,11 +489,17 @@ public class ImageCreatorSharp(PicSettings picSettings, ILogger= minMargin (not clipped at top) + // - Bottom edge must be <= imgHeight - minMargin (not clipped at bottom) + var maxAllowedY1 = imgHeight - textHeight - minMargin; // Maximum Y to keep bottom margin + var maxAllowedY4 = imgHeight - textHeight - minMargin; + + imgState.YPosFromBottom1 = Math.Max(minMargin, Math.Min(desiredY1, maxAllowedY1)); + imgState.YPosFromBottom4 = Math.Max(minMargin, Math.Min(desiredY4, maxAllowedY4)); + break; + + case "CENTRO": + default: + // Center the text vertically + var centeredY = (imgHeight - textHeight) / 2f; + // Clamp to ensure margins are respected + imgState.YPosFromBottom1 = Math.Max(minMargin, Math.Min(centeredY, imgHeight - textHeight - minMargin)); + imgState.YPosFromBottom4 = imgState.YPosFromBottom1; break; } } diff --git a/MaddoShared/MaddoShared.csproj b/MaddoShared/MaddoShared.csproj index 502345d..e95dcf4 100644 --- a/MaddoShared/MaddoShared.csproj +++ b/MaddoShared/MaddoShared.csproj @@ -9,7 +9,6 @@ - all @@ -20,7 +19,7 @@ - + @@ -28,6 +27,6 @@ all - + \ No newline at end of file diff --git a/MaddoShared/PicSettings.cs b/MaddoShared/PicSettings.cs index 8df3136..7472b63 100644 --- a/MaddoShared/PicSettings.cs +++ b/MaddoShared/PicSettings.cs @@ -38,9 +38,10 @@ public class PicSettings public int LogoLarghezza { get; set; } public Color FontColoreRGB { get; set; } public bool LogoAggiungi { get; set; } - public string LogoNomeFile { get; set; } - public string LogoTrasparenza { get; set; } - public string LogoMargine { get; set; } + // Initialize logo-related strings to safe defaults to avoid null reference issues + public string LogoNomeFile { get; set; } = string.Empty; + public string LogoTrasparenza { get; set; } = "100"; + public string LogoMargine { get; set; } = "0"; public string LogoPosizioneH { get; set; } public string LogoPosizioneV { get; set; } public bool FotoGrandeDimOrigina { get; set; } diff --git a/imagecatalog/DataModel.cs b/imagecatalog/DataModel.cs index 49a715d..83359d2 100644 --- a/imagecatalog/DataModel.cs +++ b/imagecatalog/DataModel.cs @@ -846,6 +846,8 @@ namespace ImageCatalog_2 private ConcurrentBag _results = new(); private int _currentAmount = 0; private int _previousAmount = 0; + // Atomic counter for processed images — avoids expensive ConcurrentBag.Count enumerations + private int _processedAtomic = 0; private System.Threading.Timer? _speedTimer; private void Test(object parameter) @@ -875,7 +877,7 @@ namespace ImageCatalog_2 ProcessingStatus = "Elaborazione in corso..."; TotalImagesCount = 0; ProcessedImagesCount = 0; - SpeedCounter = "-f/m"; + SpeedCounter = "-f/s"; ProgressBarValue = 0; ProgressBarMaximum = 100; @@ -902,9 +904,10 @@ namespace ImageCatalog_2 _results = new ConcurrentBag(); _currentAmount = 0; _previousAmount = 0; + _processedAtomic = 0; - // Start speed timer (every minute) - _speedTimer = new System.Threading.Timer(UpdateSpeedCounter, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); + // Start speed timer (sample every second using lightweight atomic reads) + _speedTimer = new System.Threading.Timer(UpdateSpeedCounter, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)); var time = await _imageCreationService.CreaCatalogoParallel( imageCreationOptions, @@ -940,17 +943,21 @@ namespace ImageCatalog_2 private void UpdateSpeedCounter(object? state) { _previousAmount = _currentAmount; - _currentAmount = _results.Count; + // Read the atomic counter without enumerating the ConcurrentBag + _currentAmount = System.Threading.Volatile.Read(ref _processedAtomic); int diff = _currentAmount - _previousAmount; - SpeedCounter = $"{diff} f/m"; + // Report files per second (timer runs every 1s) + SpeedCounter = $"{diff} f/s"; } private void OnImageProcessed(object? sender, Tuple args) { - ProcessedImagesCount = _results.Count; + // Increment atomic processed counter once and use its value for all UI updates + var processed = System.Threading.Interlocked.Increment(ref _processedAtomic); + ProcessedImagesCount = processed; TotalImagesCount = args.Item2; ProgressBarMaximum = args.Item2; - ProgressBarValue = _results.Count; + ProgressBarValue = processed; ProcessingStatus = args.Item1; } @@ -1044,4 +1051,6 @@ namespace ImageCatalog_2 await _settingsService.LoadSettingsAsync(filePath, this); } } -} \ No newline at end of file +} + + diff --git a/imagecatalog/ImageCatalog 2.csproj b/imagecatalog/ImageCatalog 2.csproj index aed7099..e3cdec0 100644 --- a/imagecatalog/ImageCatalog 2.csproj +++ b/imagecatalog/ImageCatalog 2.csproj @@ -42,7 +42,7 @@ - + all