diff --git a/Catalog.sln b/Catalog.sln index 958365d..a5fd6f7 100644 --- a/Catalog.sln +++ b/Catalog.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 -VisualStudioVersion = 18.2.11415.280 d18.0 +VisualStudioVersion = 18.2.11415.280 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageCatalog 2", "imagecatalog\ImageCatalog 2.csproj", "{3F1E23DB-435E-0590-1EF5-735E898DBA3C}" EndProject @@ -13,6 +13,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{5F0BEF23 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaddoShared.Tests", "MaddoShared.Tests\MaddoShared.Tests.csproj", "{59952BE8-20B4-4BF2-9367-705F41395265}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaddoShared.Benchmarks", "MaddoShared.Benchmarks\MaddoShared.Benchmarks.csproj", "{07499348-8C15-4DCC-8316-4AD121A43C38}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -59,6 +61,18 @@ Global {59952BE8-20B4-4BF2-9367-705F41395265}.Release|x64.Build.0 = Release|Any CPU {59952BE8-20B4-4BF2-9367-705F41395265}.Release|x86.ActiveCfg = Release|Any CPU {59952BE8-20B4-4BF2-9367-705F41395265}.Release|x86.Build.0 = Release|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Debug|x64.ActiveCfg = Debug|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Debug|x64.Build.0 = Debug|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Debug|x86.ActiveCfg = Debug|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Debug|x86.Build.0 = Debug|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Release|Any CPU.Build.0 = Release|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Release|x64.ActiveCfg = Release|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Release|x64.Build.0 = Release|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Release|x86.ActiveCfg = Release|Any CPU + {07499348-8C15-4DCC-8316-4AD121A43C38}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/MaddoShared.Benchmarks/.gitignore b/MaddoShared.Benchmarks/.gitignore new file mode 100644 index 0000000..28b2fd7 --- /dev/null +++ b/MaddoShared.Benchmarks/.gitignore @@ -0,0 +1,25 @@ +# BenchmarkDotNet artifacts +BenchmarkDotNet.Artifacts/ + +# Test images generated during benchmarks +TestImages/ + +# Build outputs +bin/ +obj/ + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Results and logs +*.log +*.html +*.csv +results/ + +# Temporary files +*.tmp +*.temp diff --git a/MaddoShared.Benchmarks/BenchmarkConfig.cs b/MaddoShared.Benchmarks/BenchmarkConfig.cs new file mode 100644 index 0000000..182a392 --- /dev/null +++ b/MaddoShared.Benchmarks/BenchmarkConfig.cs @@ -0,0 +1,91 @@ +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Exporters.Csv; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Loggers; +using BenchmarkDotNet.Toolchains.InProcess.Emit; + +namespace MaddoShared.Benchmarks; + +/// +/// InProcess configuration for benchmarks requiring Windows-specific APIs +/// This avoids the net10.0-windows vs net10.0 compatibility issue +/// +public class InProcessConfig : ManualConfig +{ + public InProcessConfig() + { + AddLogger(ConsoleLogger.Default); + AddExporter(HtmlExporter.Default); + AddExporter(MarkdownExporter.GitHub); + AddExporter(CsvExporter.Default); + AddDiagnoser(MemoryDiagnoser.Default); + + // Add job with InProcess toolchain + AddJob(Job.Default + .WithToolchain(InProcessEmitToolchain.Instance) + .WithWarmupCount(1) + .WithIterationCount(3)); + + // Configuration options + WithOptions(ConfigOptions.DisableOptimizationsValidator); + WithOptions(ConfigOptions.KeepBenchmarkFiles); + } +} + +/// +/// Custom configuration for image processing benchmarks +/// Uses InProcess toolchain to avoid net10.0-windows compatibility issues +/// +public class BenchmarkConfig : ManualConfig +{ + public BenchmarkConfig() + { + // Add console logger + AddLogger(ConsoleLogger.Default); + + // Add exporters for different formats + AddExporter(HtmlExporter.Default); + AddExporter(MarkdownExporter.GitHub); + AddExporter(CsvExporter.Default); + AddExporter(RPlotExporter.Default); + + // Add diagnosers + AddDiagnoser(MemoryDiagnoser.Default); + AddDiagnoser(ThreadingDiagnoser.Default); + + // Add columns + AddColumn(StatisticColumn.Mean); + AddColumn(StatisticColumn.StdDev); + AddColumn(StatisticColumn.Error); + AddColumn(StatisticColumn.Min); + AddColumn(StatisticColumn.Max); + AddColumn(StatisticColumn.Median); + AddColumn(BaselineRatioColumn.RatioMean); + + // Customize jobs with InProcess toolchain for Windows compatibility + AddJob(Job.Default + .WithToolchain(InProcessEmitToolchain.Instance) + .WithWarmupCount(1) + .WithIterationCount(3) + .WithId("Quick")); + + AddJob(Job.Default + .WithToolchain(InProcessEmitToolchain.Instance) + .WithWarmupCount(2) + .WithIterationCount(5) + .WithId("Standard")); + } + + /// + /// Fast configuration for development and quick tests + /// + public static IConfig Fast => new ManualConfig() + .AddLogger(ConsoleLogger.Default) + .AddExporter(MarkdownExporter.GitHub) + .AddDiagnoser(MemoryDiagnoser.Default) + .AddJob(Job.Dry.WithToolchain(InProcessEmitToolchain.Instance)); // Very fast, but less accurate +} diff --git a/MaddoShared.Benchmarks/ChunkSizeBenchmarks.cs b/MaddoShared.Benchmarks/ChunkSizeBenchmarks.cs new file mode 100644 index 0000000..8ea126f --- /dev/null +++ b/MaddoShared.Benchmarks/ChunkSizeBenchmarks.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Toolchains.InProcess.Emit; +using MaddoShared.Benchmarks.Helpers; +using Microsoft.Extensions.Logging; + +namespace MaddoShared.Benchmarks; + +/// +/// Benchmarks focused on different chunk sizes for parallel processing +/// +[MemoryDiagnoser] +[Config(typeof(InProcessConfig))] +public class ChunkSizeBenchmarks +{ + private string _sourceDirectory; + private string _destinationDirectory; + private ImageCreationStuff _imageCreationStuff; + private PicSettings _picSettings; + + [Params(100)] + public int ImageCount { get; set; } + + [Params(0, 5, 10, 20, 50)] + public int ChunkSize { get; set; } + + [GlobalSetup] + public void Setup() + { + var tempBase = Path.Combine(Path.GetTempPath(), "ChunkBenchmarks", Guid.NewGuid().ToString()); + _sourceDirectory = Path.Combine(tempBase, "Source"); + _destinationDirectory = Path.Combine(tempBase, "Destination"); + + Directory.CreateDirectory(_sourceDirectory); + Directory.CreateDirectory(_destinationDirectory); + + Console.WriteLine($"Generating {ImageCount} test images for chunk size testing..."); + TestImageGenerator.GenerateTestImages(_sourceDirectory, ImageCount, width: 2000, height: 1500); + + var loggerFactory = LoggerFactory.Create(builder => + { + builder.SetMinimumLevel(LogLevel.Warning); + }); + + var logger = loggerFactory.CreateLogger(); + var imageCreatorLogger = loggerFactory.CreateLogger(); + + _picSettings = new PicSettings + { + DirectorySorgente = _sourceDirectory, + DirectoryDestinazione = _destinationDirectory, + DimStandard = 800, + DimStandardMiniatura = 200, + LarghezzaBig = 1024, + AltezzaBig = 768, + LarghezzaSmall = 200, + AltezzaSmall = 150, + CreaMiniature = true, + AggiungiScritteMiniature = false, + UsaForzaJpg = true, + UsaRotazioneAutomatica = true, + LogoAggiungi = false, + FotoGrandeDimOrigina = false, + TestoNome = false, + NomeData = false, + Suffisso = "_small", + Margine = 10, + Trasparenza = 100 + }; + + var imageCreatorService = new ImageCreatorSharp(_picSettings, imageCreatorLogger); + _imageCreationStuff = new ImageCreationStuff(logger, _picSettings, imageCreatorService); + } + + [GlobalCleanup] + public void Cleanup() + { + try + { + var tempBase = Path.GetDirectoryName(_sourceDirectory); + if (Directory.Exists(tempBase)) + { + Directory.Delete(tempBase, recursive: true); + } + } + catch (Exception ex) + { + Console.WriteLine($"Cleanup error: {ex.Message}"); + } + } + + [IterationSetup] + public void IterationSetup() + { + if (Directory.Exists(_destinationDirectory)) + { + Directory.Delete(_destinationDirectory, recursive: true); + } + Directory.CreateDirectory(_destinationDirectory); + } + + [Benchmark] + public async Task ProcessWithVariableChunkSize() + { + var options = new ImageCreationStuff.Options + { + SourcePath = _sourceDirectory, + DestinationPath = _destinationDirectory, + MaxThreads = Environment.ProcessorCount, + ChunksSize = ChunkSize, + LinearExecution = false, + AggiornaSottodirectory = false, + CreaSottocartelle = false, + FilePerCartella = 100, + SuffissoCartelle = "", + CifreContatore = 4, + NumerazioneType = NumerazioneType.Progressiva + }; + + var results = new ConcurrentBag(); + await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None); + } +} diff --git a/MaddoShared.Benchmarks/Helpers/TestImageGenerator.cs b/MaddoShared.Benchmarks/Helpers/TestImageGenerator.cs new file mode 100644 index 0000000..34f44b5 --- /dev/null +++ b/MaddoShared.Benchmarks/Helpers/TestImageGenerator.cs @@ -0,0 +1,107 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; + +namespace MaddoShared.Benchmarks.Helpers; + +/// +/// Helper class to generate test images for benchmarking +/// +[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] +public static class TestImageGenerator +{ + /// + /// Generates a set of test JPEG images in the specified directory + /// + /// Directory where images will be created + /// Number of images to generate + /// Width of each image + /// Height of each image + /// Whether to create images in subfolders + public static void GenerateTestImages( + string outputDirectory, + int imageCount, + int width = 4000, + int height = 3000, + bool includeSubfolders = false) + { + Directory.CreateDirectory(outputDirectory); + + var random = new Random(42); // Fixed seed for reproducibility + + for (int i = 0; i < imageCount; i++) + { + var targetDir = outputDirectory; + + if (includeSubfolders && i % 10 == 0) + { + targetDir = Path.Combine(outputDirectory, $"Subfolder_{i / 10}"); + Directory.CreateDirectory(targetDir); + } + + var filePath = Path.Combine(targetDir, $"test_image_{i:D5}.jpg"); + + // Skip if already exists + if (File.Exists(filePath)) + continue; + + using var bitmap = new Bitmap(width, height); + using var graphics = Graphics.FromImage(bitmap); + + // Fill with a random color background + var bgColor = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); + graphics.Clear(bgColor); + + // Draw some random shapes to make it more realistic + for (int j = 0; j < 20; j++) + { + var color = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); + var brush = new SolidBrush(color); + var x = random.Next(width); + var y = random.Next(height); + var w = random.Next(200, 800); + var h = random.Next(200, 800); + graphics.FillEllipse(brush, x, y, w, h); + } + + // Add some text + using var font = new Font("Arial", 48, FontStyle.Bold); + var text = $"Test Image {i}"; + var textBrush = new SolidBrush(Color.White); + graphics.DrawString(text, font, textBrush, new PointF(100, 100)); + + // Save as JPEG with standard quality + var encoder = GetEncoder(ImageFormat.Jpeg); + var encoderParameters = new EncoderParameters(1); + encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 85L); + + bitmap.Save(filePath, encoder, encoderParameters); + } + } + + /// + /// Cleans up generated test images + /// + public static void CleanupTestImages(string directory) + { + if (Directory.Exists(directory)) + { + Directory.Delete(directory, recursive: true); + } + } + + private static ImageCodecInfo GetEncoder(ImageFormat format) + { + var codecs = ImageCodecInfo.GetImageEncoders(); + foreach (var codec in codecs) + { + if (codec.FormatID == format.Guid) + { + return codec; + } + } + return null; + } +} diff --git a/MaddoShared.Benchmarks/ImageProcessingBenchmarks.cs b/MaddoShared.Benchmarks/ImageProcessingBenchmarks.cs new file mode 100644 index 0000000..0ed6069 --- /dev/null +++ b/MaddoShared.Benchmarks/ImageProcessingBenchmarks.cs @@ -0,0 +1,182 @@ +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Toolchains.InProcess.Emit; +using MaddoShared.Benchmarks.Helpers; +using Microsoft.Extensions.Logging; + +namespace MaddoShared.Benchmarks; + +/// +/// Benchmarks for image processing with various configurations +/// +[MemoryDiagnoser] +[Config(typeof(InProcessConfig))] +public class ImageProcessingBenchmarks +{ + private string _sourceDirectory; + private string _destinationDirectory; + private ImageCreationStuff _imageCreationStuff; + private PicSettings _picSettings; + private ILogger _logger; + private ILogger _imageCreatorLogger; + + [Params(10, 50, 100)] + public int ImageCount { get; set; } + + [Params(1, 2, 4, 8)] + public int MaxThreads { get; set; } + + [GlobalSetup] + public void Setup() + { + // Create temp directories + var tempBase = Path.Combine(Path.GetTempPath(), "ImageBenchmarks", Guid.NewGuid().ToString()); + _sourceDirectory = Path.Combine(tempBase, "Source"); + _destinationDirectory = Path.Combine(tempBase, "Destination"); + + Directory.CreateDirectory(_sourceDirectory); + Directory.CreateDirectory(_destinationDirectory); + + // Generate test images + Console.WriteLine($"Generating {ImageCount} test images..."); + TestImageGenerator.GenerateTestImages(_sourceDirectory, ImageCount, width: 2000, height: 1500); + + // Setup logging + var loggerFactory = LoggerFactory.Create(builder => + { + builder.SetMinimumLevel(LogLevel.Warning); // Reduce noise during benchmarks + }); + + _logger = loggerFactory.CreateLogger(); + _imageCreatorLogger = loggerFactory.CreateLogger(); + + // Setup PicSettings with default values + _picSettings = new PicSettings + { + DirectorySorgente = _sourceDirectory, + DirectoryDestinazione = _destinationDirectory, + DimStandard = 800, + DimStandardMiniatura = 200, + LarghezzaBig = 1024, + AltezzaBig = 768, + LarghezzaSmall = 200, + AltezzaSmall = 150, + CreaMiniature = true, + AggiungiScritteMiniature = false, + UsaForzaJpg = true, + UsaRotazioneAutomatica = true, + LogoAggiungi = false, + FotoGrandeDimOrigina = false, + TestoNome = false, + NomeData = false, + Suffisso = "_small", + Margine = 10, + Trasparenza = 100 + }; + + var imageCreatorService = new ImageCreatorSharp(_picSettings, _imageCreatorLogger); + _imageCreationStuff = new ImageCreationStuff(_logger, _picSettings, imageCreatorService); + } + + [GlobalCleanup] + public void Cleanup() + { + // Clean up temp directories + try + { + var tempBase = Path.GetDirectoryName(_sourceDirectory); + if (Directory.Exists(tempBase)) + { + Directory.Delete(tempBase, recursive: true); + } + } + catch (Exception ex) + { + Console.WriteLine($"Cleanup error: {ex.Message}"); + } + } + + [IterationSetup] + public void IterationSetup() + { + // Clean destination directory before each iteration + if (Directory.Exists(_destinationDirectory)) + { + Directory.Delete(_destinationDirectory, recursive: true); + } + Directory.CreateDirectory(_destinationDirectory); + } + + [Benchmark(Description = "Process images in parallel with chunking")] + public async Task ProcessImagesParallelWithChunks() + { + var options = new ImageCreationStuff.Options + { + SourcePath = _sourceDirectory, + DestinationPath = _destinationDirectory, + MaxThreads = MaxThreads, + ChunksSize = 10, + LinearExecution = false, + AggiornaSottodirectory = false, + CreaSottocartelle = false, + FilePerCartella = 100, + SuffissoCartelle = "", + CifreContatore = 4, + NumerazioneType = NumerazioneType.Progressiva + }; + + var results = new ConcurrentBag(); + await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None); + } + + [Benchmark(Description = "Process images in parallel without chunking")] + public async Task ProcessImagesParallelWithoutChunks() + { + var options = new ImageCreationStuff.Options + { + SourcePath = _sourceDirectory, + DestinationPath = _destinationDirectory, + MaxThreads = MaxThreads, + ChunksSize = 0, // No chunking + LinearExecution = false, + AggiornaSottodirectory = false, + CreaSottocartelle = false, + FilePerCartella = 100, + SuffissoCartelle = "", + CifreContatore = 4, + NumerazioneType = NumerazioneType.Progressiva + }; + + var results = new ConcurrentBag(); + await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None); + } + + [Benchmark(Description = "Process images linearly")] + public async Task ProcessImagesLinear() + { + var options = new ImageCreationStuff.Options + { + SourcePath = _sourceDirectory, + DestinationPath = _destinationDirectory, + MaxThreads = MaxThreads, + ChunksSize = 0, + LinearExecution = true, + AggiornaSottodirectory = false, + CreaSottocartelle = false, + FilePerCartella = 100, + SuffissoCartelle = "", + CifreContatore = 4, + NumerazioneType = NumerazioneType.Progressiva + }; + + var results = new ConcurrentBag(); + await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None); + } +} diff --git a/MaddoShared.Benchmarks/ImageSizeBenchmarks.cs b/MaddoShared.Benchmarks/ImageSizeBenchmarks.cs new file mode 100644 index 0000000..fe42fcc --- /dev/null +++ b/MaddoShared.Benchmarks/ImageSizeBenchmarks.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Toolchains.InProcess.Emit; +using MaddoShared.Benchmarks.Helpers; +using Microsoft.Extensions.Logging; + +namespace MaddoShared.Benchmarks; + +/// +/// Benchmarks for comparing performance with different image sizes +/// +[MemoryDiagnoser] +[Config(typeof(InProcessConfig))] +public class ImageSizeBenchmarks +{ + private string _sourceDirectory; + private string _destinationDirectory; + private ImageCreationStuff _imageCreationStuff; + private PicSettings _picSettings; + + [Params(50)] + public int ImageCount { get; set; } + + public enum ImageSize + { + Small, // 1280x960 + Medium, // 2560x1920 + Large, // 4000x3000 + ExtraLarge // 6000x4000 + } + + [ParamsAllValues] + public ImageSize Size { get; set; } + + [GlobalSetup] + public void Setup() + { + var tempBase = Path.Combine(Path.GetTempPath(), "SizeBenchmarks", Guid.NewGuid().ToString()); + _sourceDirectory = Path.Combine(tempBase, "Source"); + _destinationDirectory = Path.Combine(tempBase, "Destination"); + + Directory.CreateDirectory(_sourceDirectory); + Directory.CreateDirectory(_destinationDirectory); + + var (width, height) = GetDimensions(Size); + Console.WriteLine($"Generating {ImageCount} test images at {width}x{height}..."); + TestImageGenerator.GenerateTestImages(_sourceDirectory, ImageCount, width, height); + + var loggerFactory = LoggerFactory.Create(builder => + { + builder.SetMinimumLevel(LogLevel.Warning); + }); + + var logger = loggerFactory.CreateLogger(); + var imageCreatorLogger = loggerFactory.CreateLogger(); + + _picSettings = new PicSettings + { + DirectorySorgente = _sourceDirectory, + DirectoryDestinazione = _destinationDirectory, + DimStandard = 800, + DimStandardMiniatura = 200, + LarghezzaBig = 1024, + AltezzaBig = 768, + LarghezzaSmall = 200, + AltezzaSmall = 150, + CreaMiniature = true, + AggiungiScritteMiniature = false, + UsaForzaJpg = true, + UsaRotazioneAutomatica = true, + LogoAggiungi = false, + FotoGrandeDimOrigina = false, + TestoNome = false, + NomeData = false, + Suffisso = "_small", + Margine = 10, + Trasparenza = 100 + }; + + var imageCreatorService = new ImageCreatorSharp(_picSettings, imageCreatorLogger); + _imageCreationStuff = new ImageCreationStuff(logger, _picSettings, imageCreatorService); + } + + private static (int width, int height) GetDimensions(ImageSize size) + { + return size switch + { + ImageSize.Small => (1280, 960), + ImageSize.Medium => (2560, 1920), + ImageSize.Large => (4000, 3000), + ImageSize.ExtraLarge => (6000, 4000), + _ => throw new ArgumentException($"Unknown size: {size}") + }; + } + + [GlobalCleanup] + public void Cleanup() + { + try + { + var tempBase = Path.GetDirectoryName(_sourceDirectory); + if (Directory.Exists(tempBase)) + { + Directory.Delete(tempBase, recursive: true); + } + } + catch (Exception ex) + { + Console.WriteLine($"Cleanup error: {ex.Message}"); + } + } + + [IterationSetup] + public void IterationSetup() + { + if (Directory.Exists(_destinationDirectory)) + { + Directory.Delete(_destinationDirectory, recursive: true); + } + Directory.CreateDirectory(_destinationDirectory); + } + + [Benchmark] + public async Task ProcessDifferentImageSizes() + { + var options = new ImageCreationStuff.Options + { + SourcePath = _sourceDirectory, + DestinationPath = _destinationDirectory, + MaxThreads = Environment.ProcessorCount, + ChunksSize = 10, + LinearExecution = false, + AggiornaSottodirectory = false, + CreaSottocartelle = false, + FilePerCartella = 100, + SuffissoCartelle = "", + CifreContatore = 4, + NumerazioneType = NumerazioneType.Progressiva + }; + + var results = new ConcurrentBag(); + await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None); + } +} diff --git a/MaddoShared.Benchmarks/MaddoShared.Benchmarks.csproj b/MaddoShared.Benchmarks/MaddoShared.Benchmarks.csproj new file mode 100644 index 0000000..99dc727 --- /dev/null +++ b/MaddoShared.Benchmarks/MaddoShared.Benchmarks.csproj @@ -0,0 +1,21 @@ + + + + Exe + net10.0-windows + x64 + true + true + + + + + + + + + + + + + diff --git a/MaddoShared.Benchmarks/Program.cs b/MaddoShared.Benchmarks/Program.cs new file mode 100644 index 0000000..cba4a67 --- /dev/null +++ b/MaddoShared.Benchmarks/Program.cs @@ -0,0 +1,35 @@ +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Running; +using BenchmarkDotNet.Toolchains.InProcess.Emit; +using System; +using System.Linq; + +namespace MaddoShared.Benchmarks; + +internal class Program +{ + static void Main(string[] args) + { + // Check if --job argument is provided + bool hasJobArg = args.Any(a => a.Contains("--job")); + + if (hasJobArg) + { + Console.WriteLine("Note: Overriding --job argument to use InProcess toolchain"); + Console.WriteLine("This is required to avoid net10.0 vs net10.0-windows compatibility issues."); + Console.WriteLine(); + + // Remove --job arguments and add our own InProcess config + args = args.Where(a => !a.StartsWith("--job") && a != "dry" && a != "short").ToArray(); + } + + // Create configuration that always uses InProcess toolchain + var config = DefaultConfig.Instance + .WithOptions(ConfigOptions.DisableOptimizationsValidator) + .WithOptions(ConfigOptions.KeepBenchmarkFiles); + + // Run benchmarks - each class has [Config(typeof(InProcessConfig))] which provides InProcess toolchain + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); + } +} diff --git a/MaddoShared.Benchmarks/StressTestBenchmark.cs b/MaddoShared.Benchmarks/StressTestBenchmark.cs new file mode 100644 index 0000000..4d626ae --- /dev/null +++ b/MaddoShared.Benchmarks/StressTestBenchmark.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Toolchains.InProcess.Emit; +using MaddoShared.Benchmarks.Helpers; +using Microsoft.Extensions.Logging; + +namespace MaddoShared.Benchmarks; + +/// +/// Stress test benchmark for large-scale image processing +/// WARNING: This will generate a large number of images and may take significant time and disk space +/// +[MemoryDiagnoser] +[Config(typeof(InProcessConfig))] +public class StressTestBenchmark +{ + private string _sourceDirectory; + private string _destinationDirectory; + private ImageCreationStuff _imageCreationStuff; + private PicSettings _picSettings; + + [Params(500, 1000)] + public int ImageCount { get; set; } + + [GlobalSetup] + public void Setup() + { + var tempBase = Path.Combine(Path.GetTempPath(), "StressTestBenchmarks", Guid.NewGuid().ToString()); + _sourceDirectory = Path.Combine(tempBase, "Source"); + _destinationDirectory = Path.Combine(tempBase, "Destination"); + + Directory.CreateDirectory(_sourceDirectory); + Directory.CreateDirectory(_destinationDirectory); + + Console.WriteLine($"[STRESS TEST] Generating {ImageCount} test images..."); + Console.WriteLine("This may take several minutes depending on your hardware."); + + // Use smaller images for stress test to save space and time + TestImageGenerator.GenerateTestImages(_sourceDirectory, ImageCount, width: 1920, height: 1080); + + var loggerFactory = LoggerFactory.Create(builder => + { + builder.SetMinimumLevel(LogLevel.Warning); + }); + + var logger = loggerFactory.CreateLogger(); + var imageCreatorLogger = loggerFactory.CreateLogger(); + + _picSettings = new PicSettings + { + DirectorySorgente = _sourceDirectory, + DirectoryDestinazione = _destinationDirectory, + DimStandard = 800, + DimStandardMiniatura = 200, + LarghezzaBig = 1024, + AltezzaBig = 768, + LarghezzaSmall = 200, + AltezzaSmall = 150, + CreaMiniature = true, + AggiungiScritteMiniature = false, + UsaForzaJpg = true, + UsaRotazioneAutomatica = true, + LogoAggiungi = false, + FotoGrandeDimOrigina = false, + TestoNome = false, + NomeData = false, + Suffisso = "_small", + Margine = 10, + Trasparenza = 100 + }; + + var imageCreatorService = new ImageCreatorSharp(_picSettings, imageCreatorLogger); + _imageCreationStuff = new ImageCreationStuff(logger, _picSettings, imageCreatorService); + + Console.WriteLine($"[STRESS TEST] Setup complete. Ready to process {ImageCount} images."); + } + + [GlobalCleanup] + public void Cleanup() + { + Console.WriteLine("[STRESS TEST] Cleaning up test data..."); + try + { + var tempBase = Path.GetDirectoryName(_sourceDirectory); + if (Directory.Exists(tempBase)) + { + Directory.Delete(tempBase, recursive: true); + } + } + catch (Exception ex) + { + Console.WriteLine($"Cleanup error: {ex.Message}"); + } + } + + [IterationSetup] + public void IterationSetup() + { + if (Directory.Exists(_destinationDirectory)) + { + Directory.Delete(_destinationDirectory, recursive: true); + } + Directory.CreateDirectory(_destinationDirectory); + GC.Collect(GC.MaxGeneration, GCCollectionMode.Aggressive, blocking: true, compacting: true); + } + + [Benchmark(Description = "Stress test with optimal settings")] + public async Task StressTestOptimalSettings() + { + var options = new ImageCreationStuff.Options + { + SourcePath = _sourceDirectory, + DestinationPath = _destinationDirectory, + MaxThreads = Environment.ProcessorCount, + ChunksSize = 25, // Process in chunks to manage memory + LinearExecution = false, + AggiornaSottodirectory = false, + CreaSottocartelle = false, + FilePerCartella = 100, + SuffissoCartelle = "", + CifreContatore = 4, + NumerazioneType = NumerazioneType.Progressiva + }; + + var results = new ConcurrentBag(); + var startTime = DateTime.Now; + + await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None); + + var duration = DateTime.Now - startTime; + var throughput = ImageCount / duration.TotalSeconds; + + Console.WriteLine($"[STRESS TEST] Processed {results.Count}/{ImageCount} images in {duration.TotalSeconds:F2}s"); + Console.WriteLine($"[STRESS TEST] Throughput: {throughput:F2} images/second"); + } + + [Benchmark(Description = "Stress test with aggressive memory management")] + public async Task StressTestAggressiveMemoryManagement() + { + var options = new ImageCreationStuff.Options + { + SourcePath = _sourceDirectory, + DestinationPath = _destinationDirectory, + MaxThreads = Environment.ProcessorCount / 2, // Reduce threads to save memory + ChunksSize = 10, // Smaller chunks for more frequent GC + LinearExecution = false, + AggiornaSottodirectory = false, + CreaSottocartelle = false, + FilePerCartella = 100, + SuffissoCartelle = "", + CifreContatore = 4, + NumerazioneType = NumerazioneType.Progressiva + }; + + var results = new ConcurrentBag(); + var startTime = DateTime.Now; + + await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None); + + var duration = DateTime.Now - startTime; + var throughput = ImageCount / duration.TotalSeconds; + + Console.WriteLine($"[STRESS TEST] Processed {results.Count}/{ImageCount} images in {duration.TotalSeconds:F2}s"); + Console.WriteLine($"[STRESS TEST] Throughput: {throughput:F2} images/second"); + } +} diff --git a/MaddoShared/ImageCreationStuff.cs b/MaddoShared/ImageCreationStuff.cs index 04f283a..7aef4d4 100644 --- a/MaddoShared/ImageCreationStuff.cs +++ b/MaddoShared/ImageCreationStuff.cs @@ -52,6 +52,15 @@ namespace MaddoShared $"{stopwatch.Elapsed.Hours}h {stopwatch.Elapsed.Minutes}m {stopwatch.Elapsed.Seconds}s ({stopwatch.Elapsed.TotalSeconds}s)"; } + /// + /// Gets the list of files that will be processed based on the provided options. + /// Useful for benchmarking and testing to understand the scope of work. + /// + public List GetFilesToProcessPublic(Options options) + { + return GetFilesToProcess(options); + } + public async Task ProcessImagesParallel( Options options, ConcurrentBag results, diff --git a/MaddoShared/ImageCreatorSharp.cs b/MaddoShared/ImageCreatorSharp.cs index e0edfb0..0fdb25e 100644 --- a/MaddoShared/ImageCreatorSharp.cs +++ b/MaddoShared/ImageCreatorSharp.cs @@ -194,6 +194,21 @@ public class ImageCreatorSharp(PicSettings picSettings, ILogger= 0 ? '_' : ch); + } + return sb.ToString(); } private void PrepareThumbnailSize(Image g, ImageState imgState) diff --git a/imagecatalog/DataModel.cs b/imagecatalog/DataModel.cs index 83359d2..0c7d826 100644 --- a/imagecatalog/DataModel.cs +++ b/imagecatalog/DataModel.cs @@ -1010,6 +1010,8 @@ namespace ImageCatalog_2 public event EventHandler SaveSettingsRequested; public event EventHandler LoadSettingsRequested; public event EventHandler SelectColorRequested; + // Request that the View shows a message to the user (message, caption, icon) + public event EventHandler> ShowMessageRequested; private void SelectSourceFolder(object parameter) { diff --git a/imagecatalog/MainForm.Designer.cs b/imagecatalog/MainForm.Designer.cs index 266fa4f..6b1c48c 100644 --- a/imagecatalog/MainForm.Designer.cs +++ b/imagecatalog/MainForm.Designer.cs @@ -40,9 +40,9 @@ namespace ImageCatalog components = new System.ComponentModel.Container(); ProgressBar1 = new ProgressBar(); CheckBox22 = new CheckBox(); - Label43 = new Label(); bindingSource1 = new BindingSource(components); dataModelBindingSource = new BindingSource(components); + Label43 = new Label(); TabControl1 = new TabControl(); TabPage5 = new TabPage(); button1 = new Button(); @@ -181,6 +181,8 @@ namespace ImageCatalog _btnCreaCatalogoAsync = new Button(); timer1 = new System.Windows.Forms.Timer(components); dataModelBindingSource1 = new BindingSource(components); + btnOpenSourceFolder = new Button(); + btnOpenDestFolder = new Button(); ((System.ComponentModel.ISupportInitialize)bindingSource1).BeginInit(); ((System.ComponentModel.ISupportInitialize)dataModelBindingSource).BeginInit(); TabControl1.SuspendLayout(); @@ -213,36 +215,24 @@ namespace ImageCatalog // // ProgressBar1 // - ProgressBar1.Location = new Point(1168, 598); + ProgressBar1.Location = new Point(1078, 561); ProgressBar1.Margin = new Padding(6, 8, 6, 8); ProgressBar1.Name = "ProgressBar1"; - ProgressBar1.Size = new Size(416, 56); + ProgressBar1.Size = new Size(384, 52); ProgressBar1.TabIndex = 67; // // CheckBox22 // - CheckBox22.DataBindings.Add(new Binding("Checked", bindingSource1, "ShutdownSystem", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox22.AutoSize = true; - CheckBox22.Location = new Point(1168, 882); + CheckBox22.DataBindings.Add(new Binding("Checked", bindingSource1, "ShutdownSystem", true, DataSourceUpdateMode.OnPropertyChanged)); + CheckBox22.Location = new Point(1078, 827); CheckBox22.Margin = new Padding(6, 8, 6, 8); CheckBox22.Name = "CheckBox22"; - CheckBox22.Size = new Size(226, 36); + CheckBox22.Size = new Size(197, 34); CheckBox22.TabIndex = 65; CheckBox22.Text = "Arresta il sistema"; CheckBox22.UseVisualStyleBackColor = true; // - // Label43 - // - Label43.AutoSize = true; - Label43.DataBindings.Add(new Binding("Text", bindingSource1, "SpeedCounter", true)); - Label43.Location = new Point(1162, 842); - Label43.Margin = new Padding(6, 0, 6, 0); - Label43.Name = "Label43"; - Label43.Size = new Size(53, 32); - Label43.TabIndex = 64; - Label43.Text = "000"; - Label43.TextAlign = ContentAlignment.MiddleLeft; - // // bindingSource1 // bindingSource1.DataSource = dataModelBindingSource; @@ -251,6 +241,18 @@ namespace ImageCatalog // dataModelBindingSource.DataSource = typeof(ImageCatalog_2.DataModel); // + // Label43 + // + Label43.AutoSize = true; + Label43.DataBindings.Add(new Binding("Text", bindingSource1, "SpeedCounter", true)); + Label43.Location = new Point(1073, 789); + Label43.Margin = new Padding(6, 0, 6, 0); + Label43.Name = "Label43"; + Label43.Size = new Size(46, 30); + Label43.TabIndex = 64; + Label43.Text = "000"; + Label43.TextAlign = ContentAlignment.MiddleLeft; + // // TabControl1 // TabControl1.Controls.Add(TabPage5); @@ -259,11 +261,11 @@ namespace ImageCatalog TabControl1.Controls.Add(TabPage1); TabControl1.Controls.Add(TabPage4); TabControl1.DataBindings.Add(new Binding("Enabled", bindingSource1, "UiEnabled", true)); - TabControl1.Location = new Point(26, 24); + TabControl1.Location = new Point(24, 22); TabControl1.Margin = new Padding(6, 8, 6, 8); TabControl1.Name = "TabControl1"; TabControl1.SelectedIndex = 0; - TabControl1.Size = new Size(1129, 928); + TabControl1.Size = new Size(1042, 870); TabControl1.TabIndex = 63; // // TabPage5 @@ -274,11 +276,11 @@ namespace ImageCatalog TabPage5.Controls.Add(GroupBox3); TabPage5.Controls.Add(GroupBox8); TabPage5.Controls.Add(GroupBox7); - TabPage5.Location = new Point(8, 46); + TabPage5.Location = new Point(4, 39); TabPage5.Margin = new Padding(6, 8, 6, 8); TabPage5.Name = "TabPage5"; TabPage5.Padding = new Padding(6, 8, 6, 8); - TabPage5.Size = new Size(1113, 874); + TabPage5.Size = new Size(1034, 827); TabPage5.TabIndex = 4; TabPage5.Text = "Generale"; TabPage5.UseVisualStyleBackColor = true; @@ -286,10 +288,10 @@ namespace ImageCatalog // button1 // button1.DataBindings.Add(new Binding("Command", bindingSource1, "AsyncTestCommand", true)); - button1.Location = new Point(814, 768); + button1.Location = new Point(751, 720); button1.Margin = new Padding(5); button1.Name = "button1"; - button1.Size = new Size(153, 46); + button1.Size = new Size(141, 43); button1.TabIndex = 50; button1.Text = "Test Async"; button1.UseVisualStyleBackColor = true; @@ -297,10 +299,10 @@ namespace ImageCatalog // btnTest // btnTest.DataBindings.Add(new Binding("Command", bindingSource1, "TestCommand", true)); - btnTest.Location = new Point(528, 755); + btnTest.Location = new Point(487, 708); btnTest.Margin = new Padding(5); btnTest.Name = "btnTest"; - btnTest.Size = new Size(153, 46); + btnTest.Size = new Size(141, 43); btnTest.TabIndex = 49; btnTest.Text = "Test"; btnTest.UseVisualStyleBackColor = true; @@ -312,11 +314,11 @@ namespace ImageCatalog GroupBox11.Controls.Add(Panel3); GroupBox11.Controls.Add(Label8); GroupBox11.Controls.Add(Label7); - GroupBox11.Location = new Point(15, 515); + GroupBox11.Location = new Point(14, 483); GroupBox11.Margin = new Padding(6, 8, 6, 8); GroupBox11.Name = "GroupBox11"; GroupBox11.Padding = new Padding(6, 8, 6, 8); - GroupBox11.Size = new Size(414, 325); + GroupBox11.Size = new Size(382, 305); GroupBox11.TabIndex = 48; GroupBox11.TabStop = false; GroupBox11.Text = "Avanzate (ATTENZIONE)"; @@ -324,40 +326,40 @@ namespace ImageCatalog // numericUpDown2 // numericUpDown2.DataBindings.Add(new Binding("Value", bindingSource1, "ThreadsCount", true, DataSourceUpdateMode.OnPropertyChanged)); - numericUpDown2.Location = new Point(15, 118); + numericUpDown2.Location = new Point(14, 111); numericUpDown2.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); numericUpDown2.Name = "numericUpDown2"; - numericUpDown2.Size = new Size(114, 39); + numericUpDown2.Size = new Size(105, 35); numericUpDown2.TabIndex = 52; // // numericUpDown1 // numericUpDown1.DataBindings.Add(new Binding("Value", bindingSource1, "ChunkSize", true, DataSourceUpdateMode.OnPropertyChanged)); - numericUpDown1.Location = new Point(15, 62); + numericUpDown1.Location = new Point(14, 58); numericUpDown1.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); numericUpDown1.Name = "numericUpDown1"; - numericUpDown1.Size = new Size(114, 39); + numericUpDown1.Size = new Size(105, 35); numericUpDown1.TabIndex = 51; // // Panel3 // Panel3.Controls.Add(rdbNuovoMetodo); Panel3.Controls.Add(rdbVecchioMetodo); - Panel3.Location = new Point(15, 179); + Panel3.Location = new Point(14, 168); Panel3.Margin = new Padding(6, 8, 6, 8); Panel3.Name = "Panel3"; - Panel3.Size = new Size(385, 131); + Panel3.Size = new Size(355, 123); Panel3.TabIndex = 4; // // rdbNuovoMetodo // - rdbNuovoMetodo.DataBindings.Add(new Binding("Checked", bindingSource1, "UseParallelProcessing", true, DataSourceUpdateMode.OnPropertyChanged)); rdbNuovoMetodo.AutoSize = true; rdbNuovoMetodo.Checked = true; - rdbNuovoMetodo.Location = new Point(18, 69); + rdbNuovoMetodo.DataBindings.Add(new Binding("Checked", bindingSource1, "UseParallelProcessing", true, DataSourceUpdateMode.OnPropertyChanged)); + rdbNuovoMetodo.Location = new Point(17, 65); rdbNuovoMetodo.Margin = new Padding(6, 8, 6, 8); rdbNuovoMetodo.Name = "rdbNuovoMetodo"; - rdbNuovoMetodo.Size = new Size(134, 36); + rdbNuovoMetodo.Size = new Size(116, 34); rdbNuovoMetodo.TabIndex = 1; rdbNuovoMetodo.TabStop = true; rdbNuovoMetodo.Text = "Parallelo"; @@ -365,12 +367,12 @@ namespace ImageCatalog // // rdbVecchioMetodo // - rdbVecchioMetodo.DataBindings.Add(new Binding("Checked", bindingSource1, "UseSequentialProcessing", true, DataSourceUpdateMode.OnPropertyChanged)); rdbVecchioMetodo.AutoSize = true; - rdbVecchioMetodo.Location = new Point(18, 10); + rdbVecchioMetodo.DataBindings.Add(new Binding("Checked", bindingSource1, "UseSequentialProcessing", true, DataSourceUpdateMode.OnPropertyChanged)); + rdbVecchioMetodo.Location = new Point(17, 9); rdbVecchioMetodo.Margin = new Padding(6, 8, 6, 8); rdbVecchioMetodo.Name = "rdbVecchioMetodo"; - rdbVecchioMetodo.Size = new Size(122, 36); + rdbVecchioMetodo.Size = new Size(105, 34); rdbVecchioMetodo.TabIndex = 0; rdbVecchioMetodo.Text = "Lineare"; rdbVecchioMetodo.UseVisualStyleBackColor = true; @@ -378,25 +380,27 @@ namespace ImageCatalog // Label8 // Label8.AutoSize = true; - Label8.Location = new Point(138, 64); + Label8.Location = new Point(127, 60); Label8.Margin = new Padding(6, 0, 6, 0); Label8.Name = "Label8"; - Label8.Size = new Size(248, 32); + Label8.Size = new Size(215, 30); Label8.TabIndex = 3; Label8.Text = "Chunk Size (0 = MAX)"; // // Label7 // Label7.AutoSize = true; - Label7.Location = new Point(138, 120); + Label7.Location = new Point(127, 112); Label7.Margin = new Padding(6, 0, 6, 0); Label7.Name = "Label7"; - Label7.Size = new Size(213, 32); + Label7.Size = new Size(186, 30); Label7.TabIndex = 1; Label7.Text = "Threads (0 = Auto)"; // // GroupBox3 // + GroupBox3.Controls.Add(btnOpenDestFolder); + GroupBox3.Controls.Add(btnOpenSourceFolder); GroupBox3.Controls.Add(chkAggiornaSottodirectory); GroupBox3.Controls.Add(_Button3); GroupBox3.Controls.Add(_Button2); @@ -405,11 +409,11 @@ namespace ImageCatalog GroupBox3.Controls.Add(txtSorgente); GroupBox3.Controls.Add(txtDestinazione); GroupBox3.ForeColor = Color.FromArgb(0, 0, 192); - GroupBox3.Location = new Point(13, 14); + GroupBox3.Location = new Point(12, 13); GroupBox3.Margin = new Padding(6, 8, 6, 8); GroupBox3.Name = "GroupBox3"; GroupBox3.Padding = new Padding(6, 8, 6, 8); - GroupBox3.Size = new Size(1074, 248); + GroupBox3.Size = new Size(991, 232); GroupBox3.TabIndex = 35; GroupBox3.TabStop = false; GroupBox3.Text = "Directory"; @@ -418,28 +422,28 @@ namespace ImageCatalog // chkAggiornaSottodirectory.DataBindings.Add(new Binding("Checked", bindingSource1, "UpdateSubdirectories", true, DataSourceUpdateMode.OnPropertyChanged)); chkAggiornaSottodirectory.ForeColor = Color.Black; - chkAggiornaSottodirectory.Location = new Point(174, 157); + chkAggiornaSottodirectory.Location = new Point(161, 147); chkAggiornaSottodirectory.Margin = new Padding(6, 8, 6, 8); chkAggiornaSottodirectory.Name = "chkAggiornaSottodirectory"; - chkAggiornaSottodirectory.Size = new Size(515, 59); + chkAggiornaSottodirectory.Size = new Size(475, 55); chkAggiornaSottodirectory.TabIndex = 25; chkAggiornaSottodirectory.Text = "aggiorna le sottodirectory"; // // _Button3 // - _Button3.Location = new Point(1001, 99); + _Button3.Location = new Point(879, 96); _Button3.Margin = new Padding(6, 8, 6, 8); _Button3.Name = "_Button3"; - _Button3.Size = new Size(52, 50); + _Button3.Size = new Size(48, 36); _Button3.TabIndex = 6; _Button3.Text = "..."; // // _Button2 // - _Button2.Location = new Point(1001, 40); + _Button2.Location = new Point(879, 38); _Button2.Margin = new Padding(6, 8, 6, 8); _Button2.Name = "_Button2"; - _Button2.Size = new Size(52, 50); + _Button2.Size = new Size(48, 35); _Button2.TabIndex = 5; _Button2.Text = "..."; // @@ -447,10 +451,10 @@ namespace ImageCatalog // Label1.AutoSize = true; Label1.ForeColor = Color.Black; - Label1.Location = new Point(13, 46); + Label1.Location = new Point(12, 43); Label1.Margin = new Padding(6, 0, 6, 0); Label1.Name = "Label1"; - Label1.Size = new Size(111, 32); + Label1.Size = new Size(96, 30); Label1.TabIndex = 3; Label1.Text = "Sorgente"; // @@ -458,29 +462,29 @@ namespace ImageCatalog // Label2.AutoSize = true; Label2.ForeColor = Color.Black; - Label2.Location = new Point(13, 102); + Label2.Location = new Point(12, 96); Label2.Margin = new Padding(6, 0, 6, 0); Label2.Name = "Label2"; - Label2.Size = new Size(152, 32); + Label2.Size = new Size(133, 30); Label2.TabIndex = 4; Label2.Text = "Destinazione"; // // txtSorgente // txtSorgente.DataBindings.Add(new Binding("Text", bindingSource1, "SourcePath", true, DataSourceUpdateMode.OnPropertyChanged)); - txtSorgente.Location = new Point(174, 40); + txtSorgente.Location = new Point(161, 38); txtSorgente.Margin = new Padding(6, 8, 6, 8); txtSorgente.Name = "txtSorgente"; - txtSorgente.Size = new Size(810, 39); + txtSorgente.Size = new Size(706, 35); txtSorgente.TabIndex = 0; // // txtDestinazione // txtDestinazione.DataBindings.Add(new Binding("Text", bindingSource1, "DestinationPath", true, DataSourceUpdateMode.OnPropertyChanged)); - txtDestinazione.Location = new Point(174, 99); + txtDestinazione.Location = new Point(161, 93); txtDestinazione.Margin = new Padding(6, 8, 6, 8); txtDestinazione.Name = "txtDestinazione"; - txtDestinazione.Size = new Size(810, 39); + txtDestinazione.Size = new Size(706, 35); txtDestinazione.TabIndex = 1; txtDestinazione.Text = "TextBox2"; // @@ -497,11 +501,11 @@ namespace ImageCatalog GroupBox8.Controls.Add(txtFilePerCartella); GroupBox8.Controls.Add(Label32); GroupBox8.ForeColor = Color.FromArgb(0, 0, 192); - GroupBox8.Location = new Point(442, 278); + GroupBox8.Location = new Point(408, 261); GroupBox8.Margin = new Padding(6, 8, 6, 8); GroupBox8.Name = "GroupBox8"; GroupBox8.Padding = new Padding(6, 8, 6, 8); - GroupBox8.Size = new Size(416, 374); + GroupBox8.Size = new Size(384, 351); GroupBox8.TabIndex = 47; GroupBox8.TabStop = false; GroupBox8.Text = "Sottocartelle"; @@ -510,22 +514,22 @@ namespace ImageCatalog // rdbNumFiles.DataBindings.Add(new Binding("Checked", bindingSource1, "UseFileNumbering", true, DataSourceUpdateMode.OnPropertyChanged)); rdbNumFiles.ForeColor = Color.Black; - rdbNumFiles.Location = new Point(70, 315); + rdbNumFiles.Location = new Point(65, 295); rdbNumFiles.Margin = new Padding(6, 8, 6, 8); rdbNumFiles.Name = "rdbNumFiles"; - rdbNumFiles.Size = new Size(294, 40); + rdbNumFiles.Size = new Size(271, 38); rdbNumFiles.TabIndex = 38; rdbNumFiles.Text = "Numerazione files"; // // rdbNumProgressiva // - rdbNumProgressiva.DataBindings.Add(new Binding("Checked", bindingSource1, "UseProgressiveNumbering", true, DataSourceUpdateMode.OnPropertyChanged)); rdbNumProgressiva.Checked = true; + rdbNumProgressiva.DataBindings.Add(new Binding("Checked", bindingSource1, "UseProgressiveNumbering", true, DataSourceUpdateMode.OnPropertyChanged)); rdbNumProgressiva.ForeColor = Color.Black; - rdbNumProgressiva.Location = new Point(70, 275); + rdbNumProgressiva.Location = new Point(65, 258); rdbNumProgressiva.Margin = new Padding(6, 8, 6, 8); rdbNumProgressiva.Name = "rdbNumProgressiva"; - rdbNumProgressiva.Size = new Size(330, 40); + rdbNumProgressiva.Size = new Size(305, 38); rdbNumProgressiva.TabIndex = 37; rdbNumProgressiva.TabStop = true; rdbNumProgressiva.Text = "Numerazione progressiva"; @@ -533,20 +537,20 @@ namespace ImageCatalog // txtCifreContatore // txtCifreContatore.DataBindings.Add(new Binding("Text", bindingSource1, "CounterDigits", true, DataSourceUpdateMode.OnPropertyChanged)); - txtCifreContatore.Location = new Point(278, 216); + txtCifreContatore.Location = new Point(257, 202); txtCifreContatore.Margin = new Padding(6, 8, 6, 8); txtCifreContatore.Name = "txtCifreContatore"; - txtCifreContatore.Size = new Size(116, 39); + txtCifreContatore.Size = new Size(107, 35); txtCifreContatore.TabIndex = 34; txtCifreContatore.Text = "4"; // // Label34 // Label34.ForeColor = Color.Black; - Label34.Location = new Point(18, 216); + Label34.Location = new Point(17, 202); Label34.Margin = new Padding(6, 0, 6, 0); Label34.Name = "Label34"; - Label34.Size = new Size(242, 40); + Label34.Size = new Size(223, 38); Label34.TabIndex = 33; Label34.Text = "Num. cifre contatore"; Label34.TextAlign = ContentAlignment.MiddleRight; @@ -554,30 +558,30 @@ namespace ImageCatalog // txtSuffissoCartelle // txtSuffissoCartelle.DataBindings.Add(new Binding("Text", bindingSource1, "FolderSuffix", true, DataSourceUpdateMode.OnPropertyChanged)); - txtSuffissoCartelle.Location = new Point(122, 157); + txtSuffissoCartelle.Location = new Point(113, 147); txtSuffissoCartelle.Margin = new Padding(6, 8, 6, 8); txtSuffissoCartelle.Name = "txtSuffissoCartelle"; - txtSuffissoCartelle.Size = new Size(272, 39); + txtSuffissoCartelle.Size = new Size(251, 35); txtSuffissoCartelle.TabIndex = 32; txtSuffissoCartelle.Text = "TextBox20"; // // Label33 // Label33.ForeColor = Color.Black; - Label33.Location = new Point(13, 165); + Label33.Location = new Point(12, 155); Label33.Margin = new Padding(6, 0, 6, 0); Label33.Name = "Label33"; - Label33.Size = new Size(104, 40); + Label33.Size = new Size(96, 38); Label33.TabIndex = 31; Label33.Text = "Suffisso"; // // Label31 // Label31.ForeColor = Color.Black; - Label31.Location = new Point(52, 99); + Label31.Location = new Point(48, 93); Label31.Margin = new Padding(6, 0, 6, 0); Label31.Name = "Label31"; - Label31.Size = new Size(70, 40); + Label31.Size = new Size(65, 38); Label31.TabIndex = 30; Label31.Text = "ogni"; // @@ -585,30 +589,30 @@ namespace ImageCatalog // chkCreaSottocartelle.DataBindings.Add(new Binding("Checked", bindingSource1, "CreateSubfolders", true, DataSourceUpdateMode.OnPropertyChanged)); chkCreaSottocartelle.ForeColor = Color.Black; - chkCreaSottocartelle.Location = new Point(122, 40); + chkCreaSottocartelle.Location = new Point(113, 38); chkCreaSottocartelle.Margin = new Padding(6, 8, 6, 8); chkCreaSottocartelle.Name = "chkCreaSottocartelle"; - chkCreaSottocartelle.Size = new Size(242, 40); + chkCreaSottocartelle.Size = new Size(223, 38); chkCreaSottocartelle.TabIndex = 29; chkCreaSottocartelle.Text = "crea sottocartelle"; // // txtFilePerCartella // txtFilePerCartella.DataBindings.Add(new Binding("Text", bindingSource1, "FilesPerFolder", true, DataSourceUpdateMode.OnPropertyChanged)); - txtFilePerCartella.Location = new Point(122, 99); + txtFilePerCartella.Location = new Point(113, 93); txtFilePerCartella.Margin = new Padding(6, 8, 6, 8); txtFilePerCartella.Name = "txtFilePerCartella"; - txtFilePerCartella.Size = new Size(134, 39); + txtFilePerCartella.Size = new Size(124, 35); txtFilePerCartella.TabIndex = 27; txtFilePerCartella.Text = "99"; // // Label32 // Label32.ForeColor = Color.Black; - Label32.Location = new Point(278, 99); + Label32.Location = new Point(257, 93); Label32.Margin = new Padding(6, 0, 6, 0); Label32.Name = "Label32"; - Label32.Size = new Size(52, 40); + Label32.Size = new Size(48, 38); Label32.TabIndex = 28; Label32.Text = "file"; // @@ -618,11 +622,11 @@ namespace ImageCatalog GroupBox7.Controls.Add(chkRotazioneAutomatica); GroupBox7.Controls.Add(chkForzaJpg); GroupBox7.ForeColor = Color.FromArgb(0, 0, 192); - GroupBox7.Location = new Point(13, 278); + GroupBox7.Location = new Point(12, 261); GroupBox7.Margin = new Padding(6, 8, 6, 8); GroupBox7.Name = "GroupBox7"; GroupBox7.Padding = new Padding(6, 8, 6, 8); - GroupBox7.Size = new Size(416, 216); + GroupBox7.Size = new Size(384, 202); GroupBox7.TabIndex = 45; GroupBox7.TabStop = false; GroupBox7.Text = "Generale"; @@ -631,10 +635,10 @@ namespace ImageCatalog // chkSovrascriviFile.AutoSize = true; chkSovrascriviFile.DataBindings.Add(new Binding("Checked", bindingSource1, "OverwriteImages", true, DataSourceUpdateMode.OnPropertyChanged)); - chkSovrascriviFile.Location = new Point(34, 150); + chkSovrascriviFile.Location = new Point(31, 141); chkSovrascriviFile.Margin = new Padding(6, 8, 6, 8); chkSovrascriviFile.Name = "chkSovrascriviFile"; - chkSovrascriviFile.Size = new Size(198, 36); + chkSovrascriviFile.Size = new Size(170, 34); chkSovrascriviFile.TabIndex = 2; chkSovrascriviFile.Text = "Sovrascrivi file"; chkSovrascriviFile.UseVisualStyleBackColor = true; @@ -643,23 +647,23 @@ namespace ImageCatalog // chkRotazioneAutomatica.DataBindings.Add(new Binding("Checked", bindingSource1, "AutomaticRotation", true, DataSourceUpdateMode.OnPropertyChanged)); chkRotazioneAutomatica.ForeColor = Color.Black; - chkRotazioneAutomatica.Location = new Point(34, 96); + chkRotazioneAutomatica.Location = new Point(31, 90); chkRotazioneAutomatica.Margin = new Padding(6, 8, 6, 8); chkRotazioneAutomatica.Name = "chkRotazioneAutomatica"; - chkRotazioneAutomatica.Size = new Size(294, 40); + chkRotazioneAutomatica.Size = new Size(271, 38); chkRotazioneAutomatica.TabIndex = 1; chkRotazioneAutomatica.Text = "Rotazione automatica"; // // chkForzaJpg // - chkForzaJpg.DataBindings.Add(new Binding("Checked", bindingSource1, "ForceJpeg", true, DataSourceUpdateMode.OnPropertyChanged)); chkForzaJpg.Checked = true; chkForzaJpg.CheckState = CheckState.Checked; + chkForzaJpg.DataBindings.Add(new Binding("Checked", bindingSource1, "ForceJpeg", true, DataSourceUpdateMode.OnPropertyChanged)); chkForzaJpg.ForeColor = Color.Black; - chkForzaJpg.Location = new Point(34, 45); + chkForzaJpg.Location = new Point(31, 42); chkForzaJpg.Margin = new Padding(6, 8, 6, 8); chkForzaJpg.Name = "chkForzaJpg"; - chkForzaJpg.Size = new Size(174, 40); + chkForzaJpg.Size = new Size(161, 38); chkForzaJpg.TabIndex = 0; chkForzaJpg.Text = "Forza Jpg"; // @@ -669,11 +673,11 @@ namespace ImageCatalog TabPage3.Controls.Add(GroupBox9); TabPage3.Controls.Add(GroupBox5); TabPage3.Controls.Add(GroupBox4); - TabPage3.Location = new Point(8, 46); + TabPage3.Location = new Point(4, 39); TabPage3.Margin = new Padding(6, 8, 6, 8); TabPage3.Name = "TabPage3"; TabPage3.Padding = new Padding(6, 8, 6, 8); - TabPage3.Size = new Size(1113, 874); + TabPage3.Size = new Size(1034, 827); TabPage3.TabIndex = 2; TabPage3.Text = "Testo"; TabPage3.UseVisualStyleBackColor = true; @@ -684,11 +688,11 @@ namespace ImageCatalog GroupBox10.Controls.Add(Label41); GroupBox10.Controls.Add(TextBox31); GroupBox10.Controls.Add(TextBox30); - GroupBox10.Location = new Point(684, 192); + GroupBox10.Location = new Point(631, 180); GroupBox10.Margin = new Padding(6, 8, 6, 8); GroupBox10.Name = "GroupBox10"; GroupBox10.Padding = new Padding(6, 8, 6, 8); - GroupBox10.Size = new Size(403, 179); + GroupBox10.Size = new Size(372, 168); GroupBox10.TabIndex = 39; GroupBox10.TabStop = false; GroupBox10.Text = "Testo foto verticali"; @@ -696,74 +700,74 @@ namespace ImageCatalog // Label42 // Label42.AutoSize = true; - Label42.Location = new Point(15, 114); + Label42.Location = new Point(14, 107); Label42.Margin = new Padding(6, 0, 6, 0); Label42.Name = "Label42"; - Label42.Size = new Size(103, 32); + Label42.Size = new Size(90, 30); Label42.TabIndex = 3; Label42.Text = "Margine"; // // Label41 // Label41.AutoSize = true; - Label41.Location = new Point(15, 61); + Label41.Location = new Point(14, 57); Label41.Margin = new Padding(6, 0, 6, 0); Label41.Name = "Label41"; - Label41.Size = new Size(246, 32); + Label41.Size = new Size(214, 30); Label41.TabIndex = 2; Label41.Text = "Dimensione Carattere"; // // TextBox31 // TextBox31.DataBindings.Add(new Binding("Text", bindingSource1, "VerticalTextMargin", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox31.Location = new Point(284, 114); + TextBox31.Location = new Point(262, 107); TextBox31.Margin = new Padding(6, 8, 6, 8); TextBox31.Name = "TextBox31"; - TextBox31.Size = new Size(80, 39); + TextBox31.Size = new Size(74, 35); TextBox31.TabIndex = 1; // // TextBox30 // TextBox30.DataBindings.Add(new Binding("Text", bindingSource1, "VerticalTextSize", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox30.Location = new Point(284, 54); + TextBox30.Location = new Point(262, 51); TextBox30.Margin = new Padding(6, 8, 6, 8); TextBox30.Name = "TextBox30"; - TextBox30.Size = new Size(80, 39); + TextBox30.Size = new Size(74, 35); TextBox30.TabIndex = 0; // // GroupBox9 // GroupBox9.Controls.Add(CheckBox17); GroupBox9.Controls.Add(CheckBox16); - GroupBox9.Location = new Point(684, 77); + GroupBox9.Location = new Point(631, 72); GroupBox9.Margin = new Padding(6, 8, 6, 8); GroupBox9.Name = "GroupBox9"; GroupBox9.Padding = new Padding(6, 8, 6, 8); - GroupBox9.Size = new Size(403, 110); + GroupBox9.Size = new Size(372, 103); GroupBox9.TabIndex = 38; GroupBox9.TabStop = false; GroupBox9.Text = "Slide show"; // // CheckBox17 // - CheckBox17.DataBindings.Add(new Binding("Checked", bindingSource1, "ShowPhotoNumber", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox17.AutoSize = true; - CheckBox17.Location = new Point(208, 45); + CheckBox17.DataBindings.Add(new Binding("Checked", bindingSource1, "ShowPhotoNumber", true, DataSourceUpdateMode.OnPropertyChanged)); + CheckBox17.Location = new Point(192, 42); CheckBox17.Margin = new Padding(6, 8, 6, 8); CheckBox17.Name = "CheckBox17"; - CheckBox17.Size = new Size(185, 36); + CheckBox17.Size = new Size(159, 34); CheckBox17.TabIndex = 1; CheckBox17.Text = "Numero foto"; CheckBox17.UseVisualStyleBackColor = true; // // CheckBox16 // - CheckBox16.DataBindings.Add(new Binding("Checked", bindingSource1, "ShowDate", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox16.AutoSize = true; - CheckBox16.Location = new Point(13, 46); + CheckBox16.DataBindings.Add(new Binding("Checked", bindingSource1, "ShowDate", true, DataSourceUpdateMode.OnPropertyChanged)); + CheckBox16.Location = new Point(12, 43); CheckBox16.Margin = new Padding(6, 8, 6, 8); CheckBox16.Name = "CheckBox16"; - CheckBox16.Size = new Size(95, 36); + CheckBox16.Size = new Size(83, 34); CheckBox16.TabIndex = 0; CheckBox16.Text = "Data"; CheckBox16.UseVisualStyleBackColor = true; @@ -781,11 +785,11 @@ namespace ImageCatalog GroupBox5.Controls.Add(Label11); GroupBox5.Controls.Add(CheckBox3); GroupBox5.ForeColor = Color.FromArgb(0, 0, 192); - GroupBox5.Location = new Point(13, 77); + GroupBox5.Location = new Point(12, 72); GroupBox5.Margin = new Padding(6, 8, 6, 8); GroupBox5.Name = "GroupBox5"; GroupBox5.Padding = new Padding(6, 8, 6, 8); - GroupBox5.Size = new Size(658, 296); + GroupBox5.Size = new Size(607, 278); GroupBox5.TabIndex = 37; GroupBox5.TabStop = false; GroupBox5.Text = "Carattere"; @@ -793,30 +797,30 @@ namespace ImageCatalog // TextBox34 // TextBox34.DataBindings.Add(new Binding("Text", bindingSource1, "TextColorRGB", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox34.Location = new Point(346, 224); + TextBox34.Location = new Point(319, 210); TextBox34.Margin = new Padding(6, 8, 6, 8); TextBox34.Name = "TextBox34"; - TextBox34.Size = new Size(116, 39); + TextBox34.Size = new Size(107, 35); TextBox34.TabIndex = 36; TextBox34.TextAlign = HorizontalAlignment.Right; // // _Button8 // _Button8.ForeColor = Color.Black; - _Button8.Location = new Point(481, 219); + _Button8.Location = new Point(444, 205); _Button8.Margin = new Padding(6, 8, 6, 8); _Button8.Name = "_Button8"; - _Button8.Size = new Size(161, 59); + _Button8.Size = new Size(149, 55); _Button8.TabIndex = 35; _Button8.Text = "Scegli..."; // // Label36 // Label36.ForeColor = Color.Black; - Label36.Location = new Point(18, 147); + Label36.Location = new Point(17, 138); Label36.Margin = new Padding(6, 0, 6, 0); Label36.Name = "Label36"; - Label36.Size = new Size(260, 46); + Label36.Size = new Size(240, 43); Label36.TabIndex = 34; Label36.Text = "Dimensione miniatura"; Label36.TextAlign = ContentAlignment.MiddleLeft; @@ -824,20 +828,20 @@ namespace ImageCatalog // TextBox25 // TextBox25.DataBindings.Add(new Binding("Text", bindingSource1, "FontSizeThumbnail", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox25.Location = new Point(346, 146); + TextBox25.Location = new Point(319, 137); TextBox25.Margin = new Padding(6, 8, 6, 8); TextBox25.Name = "TextBox25"; - TextBox25.Size = new Size(116, 39); + TextBox25.Size = new Size(107, 35); TextBox25.TabIndex = 33; TextBox25.Text = "TextBox25"; // // Label35 // Label35.ForeColor = Color.Black; - Label35.Location = new Point(18, 229); + Label35.Location = new Point(17, 215); Label35.Margin = new Padding(6, 0, 6, 0); Label35.Name = "Label35"; - Label35.Size = new Size(156, 40); + Label35.Size = new Size(144, 38); Label35.TabIndex = 32; Label35.Text = "Colore RGB"; Label35.TextAlign = ContentAlignment.MiddleLeft; @@ -845,20 +849,20 @@ namespace ImageCatalog // ComboBox3 // ComboBox3.DataBindings.Add(new Binding("Text", bindingSource1, "FontName", true, DataSourceUpdateMode.OnPropertyChanged)); - ComboBox3.Location = new Point(208, 19); + ComboBox3.Location = new Point(192, 18); ComboBox3.Margin = new Padding(6, 8, 6, 8); ComboBox3.Name = "ComboBox3"; - ComboBox3.Size = new Size(256, 40); + ComboBox3.Size = new Size(237, 38); ComboBox3.TabIndex = 28; ComboBox3.Text = "ComboBox3"; // // TextBox11 // TextBox11.DataBindings.Add(new Binding("Text", bindingSource1, "FontSize", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox11.Location = new Point(346, 86); + TextBox11.Location = new Point(319, 81); TextBox11.Margin = new Padding(6, 8, 6, 8); TextBox11.Name = "TextBox11"; - TextBox11.Size = new Size(116, 39); + TextBox11.Size = new Size(107, 35); TextBox11.TabIndex = 27; TextBox11.Text = "TextBox11"; // @@ -866,10 +870,10 @@ namespace ImageCatalog // Label12.AutoSize = true; Label12.ForeColor = Color.Black; - Label12.Location = new Point(18, 93); + Label12.Location = new Point(17, 87); Label12.Margin = new Padding(6, 0, 6, 0); Label12.Name = "Label12"; - Label12.Size = new Size(142, 32); + Label12.Size = new Size(123, 30); Label12.TabIndex = 26; Label12.Text = "Dimensione"; Label12.TextAlign = ContentAlignment.MiddleLeft; @@ -878,10 +882,10 @@ namespace ImageCatalog // Label11.AutoSize = true; Label11.ForeColor = Color.Black; - Label11.Location = new Point(122, 19); + Label11.Location = new Point(113, 18); Label11.Margin = new Padding(6, 0, 6, 0); Label11.Name = "Label11"; - Label11.Size = new Size(62, 32); + Label11.Size = new Size(54, 30); Label11.TabIndex = 22; Label11.Text = "Font"; // @@ -889,10 +893,10 @@ namespace ImageCatalog // CheckBox3.DataBindings.Add(new Binding("Checked", bindingSource1, "FontBold", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox3.ForeColor = Color.Black; - CheckBox3.Location = new Point(486, 19); + CheckBox3.Location = new Point(449, 18); CheckBox3.Margin = new Padding(6, 8, 6, 8); CheckBox3.Name = "CheckBox3"; - CheckBox3.Size = new Size(156, 59); + CheckBox3.Size = new Size(144, 55); CheckBox3.TabIndex = 24; CheckBox3.Text = "Grassetto"; // @@ -916,11 +920,11 @@ namespace ImageCatalog GroupBox4.Controls.Add(TextBox12); GroupBox4.Controls.Add(Label15); GroupBox4.ForeColor = Color.FromArgb(0, 0, 192); - GroupBox4.Location = new Point(13, 387); + GroupBox4.Location = new Point(12, 363); GroupBox4.Margin = new Padding(6, 8, 6, 8); GroupBox4.Name = "GroupBox4"; GroupBox4.Padding = new Padding(6, 8, 6, 8); - GroupBox4.Size = new Size(1074, 458); + GroupBox4.Size = new Size(991, 429); GroupBox4.TabIndex = 36; GroupBox4.TabStop = false; GroupBox4.Text = "Testo da applicare"; @@ -928,40 +932,40 @@ namespace ImageCatalog // Label40 // Label40.AutoSize = true; - Label40.Location = new Point(18, 128); + Label40.Location = new Point(17, 120); Label40.Margin = new Padding(6, 0, 6, 0); Label40.Name = "Label40"; - Label40.Size = new Size(104, 32); + Label40.Size = new Size(92, 30); Label40.TabIndex = 40; Label40.Text = "Verticale"; // // TextBox29 // TextBox29.DataBindings.Add(new Binding("Text", bindingSource1, "VerticalText", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox29.Location = new Point(156, 120); + TextBox29.Location = new Point(144, 112); TextBox29.Margin = new Padding(6, 8, 6, 8); TextBox29.Multiline = true; TextBox29.Name = "TextBox29"; - TextBox29.Size = new Size(880, 103); + TextBox29.Size = new Size(813, 97); TextBox29.TabIndex = 39; // // TextBox18 // TextBox18.DataBindings.Add(new Binding("Text", bindingSource1, "TimeLabel", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox18.Location = new Point(502, 384); + TextBox18.Location = new Point(463, 360); TextBox18.Margin = new Padding(6, 8, 6, 8); TextBox18.Name = "TextBox18"; - TextBox18.Size = new Size(212, 39); + TextBox18.Size = new Size(196, 35); TextBox18.TabIndex = 38; // // Label26 // Label26.AutoSize = true; Label26.ForeColor = Color.Black; - Label26.Location = new Point(746, 384); + Label26.Location = new Point(689, 360); Label26.Margin = new Padding(6, 0, 6, 0); Label26.Name = "Label26"; - Label26.Size = new Size(106, 32); + Label26.Size = new Size(94, 30); Label26.TabIndex = 37; Label26.Text = "partenza"; // @@ -969,30 +973,30 @@ namespace ImageCatalog // DateTimePicker1.DataBindings.Add(new Binding("Value", bindingSource1, "RaceStartDate", true, DataSourceUpdateMode.OnPropertyChanged)); DateTimePicker1.Format = DateTimePickerFormat.Time; - DateTimePicker1.Location = new Point(850, 384); + DateTimePicker1.Location = new Point(785, 360); DateTimePicker1.Margin = new Padding(6, 8, 6, 8); DateTimePicker1.Name = "DateTimePicker1"; - DateTimePicker1.Size = new Size(186, 39); + DateTimePicker1.Size = new Size(172, 35); DateTimePicker1.TabIndex = 36; // // CheckBox8 // CheckBox8.DataBindings.Add(new Binding("Checked", bindingSource1, "AddTime", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox8.ForeColor = Color.Black; - CheckBox8.Location = new Point(156, 384); + CheckBox8.Location = new Point(144, 360); CheckBox8.Margin = new Padding(6, 8, 6, 8); CheckBox8.Name = "CheckBox8"; - CheckBox8.Size = new Size(122, 40); + CheckBox8.Size = new Size(113, 38); CheckBox8.TabIndex = 35; CheckBox8.Text = "Orario"; // // TextBox9 // TextBox9.DataBindings.Add(new Binding("Text", bindingSource1, "TextTransparency", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox9.Location = new Point(260, 266); + TextBox9.Location = new Point(240, 249); TextBox9.Margin = new Padding(6, 8, 6, 8); TextBox9.Name = "TextBox9"; - TextBox9.Size = new Size(116, 39); + TextBox9.Size = new Size(107, 35); TextBox9.TabIndex = 20; TextBox9.Text = "TextBox9"; // @@ -1000,10 +1004,10 @@ namespace ImageCatalog // CheckBox7.DataBindings.Add(new Binding("Checked", bindingSource1, "AddRaceTime", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox7.ForeColor = Color.Black; - CheckBox7.Location = new Point(294, 384); + CheckBox7.Location = new Point(271, 360); CheckBox7.Margin = new Padding(6, 8, 6, 8); CheckBox7.Name = "CheckBox7"; - CheckBox7.Size = new Size(190, 40); + CheckBox7.Size = new Size(175, 38); CheckBox7.TabIndex = 34; CheckBox7.Text = "Tempo gara"; // @@ -1011,30 +1015,30 @@ namespace ImageCatalog // Label4.AutoSize = true; Label4.ForeColor = Color.Black; - Label4.Location = new Point(18, 59); + Label4.Location = new Point(17, 55); Label4.Margin = new Padding(6, 0, 6, 0); Label4.Name = "Label4"; - Label4.Size = new Size(135, 32); + Label4.Size = new Size(119, 30); Label4.TabIndex = 9; Label4.Text = "Orizzontale"; // // TextBox4 // TextBox4.DataBindings.Add(new Binding("Text", bindingSource1, "HorizontalText", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox4.Location = new Point(156, 59); + TextBox4.Location = new Point(144, 55); TextBox4.Margin = new Padding(6, 8, 6, 8); TextBox4.Name = "TextBox4"; - TextBox4.Size = new Size(880, 39); + TextBox4.Size = new Size(813, 35); TextBox4.TabIndex = 8; // // Label9 // Label9.AutoSize = true; Label9.ForeColor = Color.Black; - Label9.Location = new Point(18, 266); + Label9.Location = new Point(17, 249); Label9.Margin = new Padding(6, 0, 6, 0); Label9.Name = "Label9"; - Label9.Size = new Size(242, 32); + Label9.Size = new Size(210, 30); Label9.TabIndex = 19; Label9.Text = "Trasparenza (0-100%)"; // @@ -1042,30 +1046,30 @@ namespace ImageCatalog // Label13.AutoSize = true; Label13.ForeColor = Color.Black; - Label13.Location = new Point(34, 325); + Label13.Location = new Point(31, 305); Label13.Margin = new Padding(6, 0, 6, 0); Label13.Name = "Label13"; - Label13.Size = new Size(114, 32); + Label13.Size = new Size(100, 30); Label13.TabIndex = 29; Label13.Text = "Posizione"; // // ComboBox1 // ComboBox1.DataBindings.Add(new Binding("Text", bindingSource1, "VerticalPosition", true, DataSourceUpdateMode.OnPropertyChanged)); - ComboBox1.Location = new Point(156, 325); + ComboBox1.Location = new Point(144, 305); ComboBox1.Margin = new Padding(6, 8, 6, 8); ComboBox1.Name = "ComboBox1"; - ComboBox1.Size = new Size(220, 40); + ComboBox1.Size = new Size(203, 38); ComboBox1.TabIndex = 28; ComboBox1.Text = "ComboBox1"; // // ComboBox2 // ComboBox2.DataBindings.Add(new Binding("Text", bindingSource1, "HorizontalAlignment", true, DataSourceUpdateMode.OnPropertyChanged)); - ComboBox2.Location = new Point(814, 325); + ComboBox2.Location = new Point(751, 305); ComboBox2.Margin = new Padding(6, 8, 6, 8); ComboBox2.Name = "ComboBox2"; - ComboBox2.Size = new Size(220, 40); + ComboBox2.Size = new Size(203, 38); ComboBox2.TabIndex = 31; ComboBox2.Text = "ComboBox2"; // @@ -1073,20 +1077,20 @@ namespace ImageCatalog // Label14.AutoSize = true; Label14.ForeColor = Color.Black; - Label14.Location = new Point(658, 325); + Label14.Location = new Point(607, 305); Label14.Margin = new Padding(6, 0, 6, 0); Label14.Name = "Label14"; - Label14.Size = new Size(156, 32); + Label14.Size = new Size(136, 30); Label14.TabIndex = 30; Label14.Text = "Allineamento"; // // TextBox12 // TextBox12.DataBindings.Add(new Binding("Text", bindingSource1, "TextMargin", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox12.Location = new Point(814, 266); + TextBox12.Location = new Point(751, 249); TextBox12.Margin = new Padding(6, 8, 6, 8); TextBox12.Name = "TextBox12"; - TextBox12.Size = new Size(220, 39); + TextBox12.Size = new Size(203, 35); TextBox12.TabIndex = 33; TextBox12.Text = "TextBox12"; // @@ -1094,21 +1098,21 @@ namespace ImageCatalog // Label15.AutoSize = true; Label15.ForeColor = Color.Black; - Label15.Location = new Point(642, 266); + Label15.Location = new Point(593, 249); Label15.Margin = new Padding(6, 0, 6, 0); Label15.Name = "Label15"; - Label15.Size = new Size(174, 32); + Label15.Size = new Size(151, 30); Label15.TabIndex = 32; Label15.Text = "Margine (pixel)"; // // TabPage2 // TabPage2.Controls.Add(GroupBox2); - TabPage2.Location = new Point(8, 46); + TabPage2.Location = new Point(4, 39); TabPage2.Margin = new Padding(6, 8, 6, 8); TabPage2.Name = "TabPage2"; TabPage2.Padding = new Padding(6, 8, 6, 8); - TabPage2.Size = new Size(1113, 874); + TabPage2.Size = new Size(1034, 827); TabPage2.TabIndex = 5; TabPage2.Text = "Foto"; TabPage2.UseVisualStyleBackColor = true; @@ -1125,11 +1129,11 @@ namespace ImageCatalog GroupBox2.Controls.Add(TextBox28); GroupBox2.Controls.Add(CheckBox15); GroupBox2.ForeColor = Color.FromArgb(0, 0, 192); - GroupBox2.Location = new Point(6, 14); + GroupBox2.Location = new Point(6, 13); GroupBox2.Margin = new Padding(6, 8, 6, 8); GroupBox2.Name = "GroupBox2"; GroupBox2.Padding = new Padding(6, 8, 6, 8); - GroupBox2.Size = new Size(658, 384); + GroupBox2.Size = new Size(607, 360); GroupBox2.TabIndex = 36; GroupBox2.TabStop = false; GroupBox2.Text = "Foto grande"; @@ -1137,39 +1141,39 @@ namespace ImageCatalog // Label45 // Label45.AutoSize = true; - Label45.Location = new Point(24, 211); + Label45.Location = new Point(22, 198); Label45.Margin = new Padding(6, 0, 6, 0); Label45.Name = "Label45"; - Label45.Size = new Size(90, 32); + Label45.Size = new Size(80, 30); Label45.TabIndex = 22; Label45.Text = "Qualità"; // // TextBox32 // TextBox32.DataBindings.Add(new Binding("Text", bindingSource1, "JpegQuality", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox32.Location = new Point(156, 197); + TextBox32.Location = new Point(144, 185); TextBox32.Margin = new Padding(6, 8, 6, 8); TextBox32.Name = "TextBox32"; - TextBox32.Size = new Size(152, 39); + TextBox32.Size = new Size(141, 35); TextBox32.TabIndex = 21; TextBox32.Text = "100"; // // TextBox26 // TextBox26.DataBindings.Add(new Binding("Text", bindingSource1, "BigPhotoSuffix", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox26.Location = new Point(486, 118); + TextBox26.Location = new Point(449, 111); TextBox26.Margin = new Padding(6, 8, 6, 8); TextBox26.Name = "TextBox26"; - TextBox26.Size = new Size(116, 39); + TextBox26.Size = new Size(107, 35); TextBox26.TabIndex = 20; // // Label37 // Label37.ForeColor = Color.Black; - Label37.Location = new Point(364, 118); + Label37.Location = new Point(336, 111); Label37.Margin = new Padding(6, 0, 6, 0); Label37.Name = "Label37"; - Label37.Size = new Size(104, 40); + Label37.Size = new Size(96, 38); Label37.TabIndex = 19; Label37.Text = "Suffisso"; Label37.TextAlign = ContentAlignment.MiddleRight; @@ -1178,20 +1182,20 @@ namespace ImageCatalog // Label38.AutoSize = true; Label38.ForeColor = Color.Black; - Label38.Location = new Point(52, 59); + Label38.Location = new Point(48, 55); Label38.Margin = new Padding(6, 0, 6, 0); Label38.Name = "Label38"; - Label38.Size = new Size(90, 32); + Label38.Size = new Size(81, 30); Label38.TabIndex = 16; Label38.Text = "Altezza"; // // TextBox27 // TextBox27.DataBindings.Add(new Binding("Text", bindingSource1, "PhotoBigWidth", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox27.Location = new Point(156, 59); + TextBox27.Location = new Point(144, 55); TextBox27.Margin = new Padding(6, 8, 6, 8); TextBox27.Name = "TextBox27"; - TextBox27.Size = new Size(152, 39); + TextBox27.Size = new Size(141, 35); TextBox27.TabIndex = 14; TextBox27.Text = "TextBox27"; // @@ -1199,33 +1203,33 @@ namespace ImageCatalog // Label39.AutoSize = true; Label39.ForeColor = Color.Black; - Label39.Location = new Point(18, 118); + Label39.Location = new Point(17, 111); Label39.Margin = new Padding(6, 0, 6, 0); Label39.Name = "Label39"; - Label39.Size = new Size(120, 32); + Label39.Size = new Size(107, 30); Label39.TabIndex = 17; Label39.Text = "Larghezza"; // // TextBox28 // TextBox28.DataBindings.Add(new Binding("Text", bindingSource1, "PhotoBigHeight", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox28.Location = new Point(156, 118); + TextBox28.Location = new Point(144, 111); TextBox28.Margin = new Padding(6, 8, 6, 8); TextBox28.Name = "TextBox28"; - TextBox28.Size = new Size(152, 39); + TextBox28.Size = new Size(141, 35); TextBox28.TabIndex = 15; TextBox28.Text = "TextBox28"; // // CheckBox15 // - CheckBox15.DataBindings.Add(new Binding("Checked", bindingSource1, "KeepOriginalDimensions", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox15.Checked = true; CheckBox15.CheckState = CheckState.Checked; + CheckBox15.DataBindings.Add(new Binding("Checked", bindingSource1, "KeepOriginalDimensions", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox15.ForeColor = Color.Black; - CheckBox15.Location = new Point(364, 40); + CheckBox15.Location = new Point(336, 38); CheckBox15.Margin = new Padding(6, 8, 6, 8); CheckBox15.Name = "CheckBox15"; - CheckBox15.Size = new Size(260, 78); + CheckBox15.Size = new Size(240, 73); CheckBox15.TabIndex = 18; CheckBox15.Text = "Mantieni dimensioni originali"; // @@ -1233,11 +1237,11 @@ namespace ImageCatalog // TabPage1.Controls.Add(Panel1); TabPage1.Controls.Add(GroupBox1); - TabPage1.Location = new Point(8, 46); + TabPage1.Location = new Point(4, 39); TabPage1.Margin = new Padding(6, 8, 6, 8); TabPage1.Name = "TabPage1"; TabPage1.Padding = new Padding(6, 8, 6, 8); - TabPage1.Size = new Size(1113, 874); + TabPage1.Size = new Size(1034, 827); TabPage1.TabIndex = 0; TabPage1.Text = "Miniature"; TabPage1.UseVisualStyleBackColor = true; @@ -1247,20 +1251,20 @@ namespace ImageCatalog Panel1.Controls.Add(_CheckBox18); Panel1.Controls.Add(_CheckBox4); Panel1.Controls.Add(_CheckBox12); - Panel1.Location = new Point(112, 581); + Panel1.Location = new Point(103, 545); Panel1.Margin = new Padding(6, 8, 6, 8); Panel1.Name = "Panel1"; - Panel1.Size = new Size(658, 179); + Panel1.Size = new Size(607, 168); Panel1.TabIndex = 26; Panel1.Visible = false; // // _CheckBox18 // _CheckBox18.AutoSize = true; - _CheckBox18.Location = new Point(304, 8); + _CheckBox18.Location = new Point(281, 8); _CheckBox18.Margin = new Padding(6, 8, 6, 8); _CheckBox18.Name = "_CheckBox18"; - _CheckBox18.Size = new Size(185, 36); + _CheckBox18.Size = new Size(159, 34); _CheckBox18.TabIndex = 36; _CheckBox18.Text = "Numero foto"; _CheckBox18.UseVisualStyleBackColor = true; @@ -1268,20 +1272,20 @@ namespace ImageCatalog // _CheckBox4 // _CheckBox4.ForeColor = Color.Black; - _CheckBox4.Location = new Point(21, 8); + _CheckBox4.Location = new Point(19, 8); _CheckBox4.Margin = new Padding(6, 8, 6, 8); _CheckBox4.Name = "_CheckBox4"; - _CheckBox4.Size = new Size(226, 42); + _CheckBox4.Size = new Size(209, 39); _CheckBox4.TabIndex = 34; _CheckBox4.Text = "Aggiungi scritta"; // // _CheckBox12 // _CheckBox12.ForeColor = Color.Black; - _CheckBox12.Location = new Point(21, 46); + _CheckBox12.Location = new Point(19, 43); _CheckBox12.Margin = new Padding(6, 8, 6, 8); _CheckBox12.Name = "_CheckBox12"; - _CheckBox12.Size = new Size(226, 51); + _CheckBox12.Size = new Size(209, 48); _CheckBox12.TabIndex = 35; _CheckBox12.Text = "Aggiungi orario"; // @@ -1298,11 +1302,11 @@ namespace ImageCatalog GroupBox1.Controls.Add(TextBox3); GroupBox1.Controls.Add(CheckBox1); GroupBox1.ForeColor = Color.FromArgb(0, 0, 192); - GroupBox1.Location = new Point(13, 13); + GroupBox1.Location = new Point(12, 12); GroupBox1.Margin = new Padding(6, 8, 6, 8); GroupBox1.Name = "GroupBox1"; GroupBox1.Padding = new Padding(6, 8, 6, 8); - GroupBox1.Size = new Size(759, 517); + GroupBox1.Size = new Size(701, 485); GroupBox1.TabIndex = 25; GroupBox1.TabStop = false; GroupBox1.Text = "Miniature"; @@ -1310,20 +1314,20 @@ namespace ImageCatalog // Label46 // Label46.AutoSize = true; - Label46.Location = new Point(429, 106); + Label46.Location = new Point(396, 99); Label46.Margin = new Padding(6, 0, 6, 0); Label46.Name = "Label46"; - Label46.Size = new Size(90, 32); + Label46.Size = new Size(80, 30); Label46.TabIndex = 21; Label46.Text = "Qualità"; // // TextBox33 // TextBox33.DataBindings.Add(new Binding("Text", bindingSource1, "JpegQualityThumbnail", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox33.Location = new Point(528, 99); + TextBox33.Location = new Point(487, 93); TextBox33.Margin = new Padding(6, 8, 6, 8); TextBox33.Name = "TextBox33"; - TextBox33.Size = new Size(212, 39); + TextBox33.Size = new Size(196, 35); TextBox33.TabIndex = 20; // // Panel2 @@ -1333,20 +1337,20 @@ namespace ImageCatalog Panel2.Controls.Add(RadioButton4); Panel2.Controls.Add(RadioButton6); Panel2.Controls.Add(RadioButton5); - Panel2.Location = new Point(122, 280); + Panel2.Location = new Point(113, 262); Panel2.Margin = new Padding(6, 8, 6, 8); Panel2.Name = "Panel2"; - Panel2.Size = new Size(509, 221); + Panel2.Size = new Size(470, 207); Panel2.TabIndex = 19; // // RadioButton3 // - RadioButton3.DataBindings.Add(new Binding("Checked", bindingSource1, "AddTextToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged)); RadioButton3.AutoSize = true; - RadioButton3.Location = new Point(32, 40); + RadioButton3.DataBindings.Add(new Binding("Checked", bindingSource1, "AddTextToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged)); + RadioButton3.Location = new Point(30, 38); RadioButton3.Margin = new Padding(6, 8, 6, 8); RadioButton3.Name = "RadioButton3"; - RadioButton3.Size = new Size(215, 36); + RadioButton3.Size = new Size(186, 34); RadioButton3.TabIndex = 14; RadioButton3.TabStop = true; RadioButton3.Text = "Aggiungi Scritta"; @@ -1354,12 +1358,12 @@ namespace ImageCatalog // // RadioButton7 // - RadioButton7.DataBindings.Add(new Binding("Checked", bindingSource1, "AddNumberAndTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged)); RadioButton7.AutoSize = true; - RadioButton7.Location = new Point(280, 99); + RadioButton7.DataBindings.Add(new Binding("Checked", bindingSource1, "AddNumberAndTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged)); + RadioButton7.Location = new Point(258, 93); RadioButton7.Margin = new Padding(6, 8, 6, 8); RadioButton7.Name = "RadioButton7"; - RadioButton7.Size = new Size(215, 36); + RadioButton7.Size = new Size(184, 34); RadioButton7.TabIndex = 18; RadioButton7.TabStop = true; RadioButton7.Text = "numero+tempo"; @@ -1368,10 +1372,10 @@ namespace ImageCatalog // RadioButton4 // RadioButton4.AutoSize = true; - RadioButton4.Location = new Point(32, 99); + RadioButton4.Location = new Point(30, 93); RadioButton4.Margin = new Padding(6, 8, 6, 8); RadioButton4.Name = "RadioButton4"; - RadioButton4.Size = new Size(211, 36); + RadioButton4.Size = new Size(182, 34); RadioButton4.TabIndex = 15; RadioButton4.TabStop = true; RadioButton4.Text = "Aggiungi orario"; @@ -1380,10 +1384,10 @@ namespace ImageCatalog // RadioButton6 // RadioButton6.AutoSize = true; - RadioButton6.Location = new Point(280, 40); + RadioButton6.Location = new Point(258, 38); RadioButton6.Margin = new Padding(6, 8, 6, 8); RadioButton6.Name = "RadioButton6"; - RadioButton6.Size = new Size(184, 36); + RadioButton6.Size = new Size(158, 34); RadioButton6.TabIndex = 17; RadioButton6.TabStop = true; RadioButton6.Text = "Numero foto"; @@ -1391,12 +1395,12 @@ namespace ImageCatalog // // RadioButton5 // - RadioButton5.DataBindings.Add(new Binding("Checked", bindingSource1, "AddRaceTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged)); RadioButton5.AutoSize = true; - RadioButton5.Location = new Point(32, 160); + RadioButton5.DataBindings.Add(new Binding("Checked", bindingSource1, "AddRaceTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged)); + RadioButton5.Location = new Point(30, 150); RadioButton5.Margin = new Padding(6, 8, 6, 8); RadioButton5.Name = "RadioButton5"; - RadioButton5.Size = new Size(173, 36); + RadioButton5.Size = new Size(149, 34); RadioButton5.TabIndex = 16; RadioButton5.TabStop = true; RadioButton5.Text = "Tempo Gara"; @@ -1406,20 +1410,20 @@ namespace ImageCatalog // Label5.AutoSize = true; Label5.ForeColor = Color.Black; - Label5.Location = new Point(52, 216); + Label5.Location = new Point(48, 202); Label5.Margin = new Padding(6, 0, 6, 0); Label5.Name = "Label5"; - Label5.Size = new Size(90, 32); + Label5.Size = new Size(81, 30); Label5.TabIndex = 12; Label5.Text = "Altezza"; // // TextBox5 // TextBox5.DataBindings.Add(new Binding("Text", bindingSource1, "ThumbnailWidth", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox5.Location = new Point(156, 157); + TextBox5.Location = new Point(144, 147); TextBox5.Margin = new Padding(6, 8, 6, 8); TextBox5.Name = "TextBox5"; - TextBox5.Size = new Size(186, 39); + TextBox5.Size = new Size(172, 35); TextBox5.TabIndex = 10; TextBox5.Text = "TextBox5"; // @@ -1427,20 +1431,20 @@ namespace ImageCatalog // Label6.AutoSize = true; Label6.ForeColor = Color.Black; - Label6.Location = new Point(18, 157); + Label6.Location = new Point(17, 147); Label6.Margin = new Padding(6, 0, 6, 0); Label6.Name = "Label6"; - Label6.Size = new Size(120, 32); + Label6.Size = new Size(107, 30); Label6.TabIndex = 13; Label6.Text = "Larghezza"; // // TextBox6 // TextBox6.DataBindings.Add(new Binding("Text", bindingSource1, "ThumbnailHeight", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox6.Location = new Point(156, 216); + TextBox6.Location = new Point(144, 202); TextBox6.Margin = new Padding(6, 8, 6, 8); TextBox6.Name = "TextBox6"; - TextBox6.Size = new Size(186, 39); + TextBox6.Size = new Size(172, 35); TextBox6.TabIndex = 11; TextBox6.Text = "TextBox6"; // @@ -1448,20 +1452,20 @@ namespace ImageCatalog // Label3.AutoSize = true; Label3.ForeColor = Color.Black; - Label3.Location = new Point(52, 99); + Label3.Location = new Point(48, 93); Label3.Margin = new Padding(6, 0, 6, 0); Label3.Name = "Label3"; - Label3.Size = new Size(97, 32); + Label3.Size = new Size(85, 30); Label3.TabIndex = 7; Label3.Text = "Suffisso"; // // TextBox3 // TextBox3.DataBindings.Add(new Binding("Text", bindingSource1, "ThumbnailPrefix", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox3.Location = new Point(156, 99); + TextBox3.Location = new Point(144, 93); TextBox3.Margin = new Padding(6, 8, 6, 8); TextBox3.Name = "TextBox3"; - TextBox3.Size = new Size(186, 39); + TextBox3.Size = new Size(172, 35); TextBox3.TabIndex = 6; TextBox3.Text = "TextBox3"; // @@ -1469,21 +1473,21 @@ namespace ImageCatalog // CheckBox1.DataBindings.Add(new Binding("Checked", bindingSource1, "CreateThumbnails", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox1.ForeColor = Color.Black; - CheckBox1.Location = new Point(156, 40); + CheckBox1.Location = new Point(144, 38); CheckBox1.Margin = new Padding(6, 8, 6, 8); CheckBox1.Name = "CheckBox1"; - CheckBox1.Size = new Size(226, 59); + CheckBox1.Size = new Size(209, 55); CheckBox1.TabIndex = 5; CheckBox1.Text = "Crea miniature"; // // TabPage4 // TabPage4.Controls.Add(GroupBox6); - TabPage4.Location = new Point(8, 46); + TabPage4.Location = new Point(4, 39); TabPage4.Margin = new Padding(6, 8, 6, 8); TabPage4.Name = "TabPage4"; TabPage4.Padding = new Padding(6, 8, 6, 8); - TabPage4.Size = new Size(1113, 874); + TabPage4.Size = new Size(1034, 827); TabPage4.TabIndex = 3; TabPage4.Text = "Logo"; TabPage4.UseVisualStyleBackColor = true; @@ -1510,11 +1514,11 @@ namespace ImageCatalog GroupBox6.Controls.Add(Label30); GroupBox6.Controls.Add(PictureBox3); GroupBox6.ForeColor = Color.FromArgb(0, 0, 192); - GroupBox6.Location = new Point(13, 14); + GroupBox6.Location = new Point(12, 13); GroupBox6.Margin = new Padding(6, 8, 6, 8); GroupBox6.Name = "GroupBox6"; GroupBox6.Padding = new Padding(6, 8, 6, 8); - GroupBox6.Size = new Size(1074, 552); + GroupBox6.Size = new Size(991, 518); GroupBox6.TabIndex = 42; GroupBox6.TabStop = false; GroupBox6.Text = "Logo"; @@ -1522,10 +1526,10 @@ namespace ImageCatalog // PictureBox2 // PictureBox2.BorderStyle = BorderStyle.FixedSingle; - PictureBox2.Location = new Point(312, 472); + PictureBox2.Location = new Point(288, 442); PictureBox2.Margin = new Padding(6, 8, 6, 8); PictureBox2.Name = "PictureBox2"; - PictureBox2.Size = new Size(49, 56); + PictureBox2.Size = new Size(45, 53); PictureBox2.TabIndex = 44; PictureBox2.TabStop = false; PictureBox2.Visible = false; @@ -1533,10 +1537,10 @@ namespace ImageCatalog // _PictureBox1 // _PictureBox1.Cursor = Cursors.Cross; - _PictureBox1.Location = new Point(554, 138); + _PictureBox1.Location = new Point(511, 129); _PictureBox1.Margin = new Padding(6, 8, 6, 8); _PictureBox1.Name = "_PictureBox1"; - _PictureBox1.Size = new Size(486, 394); + _PictureBox1.Size = new Size(449, 369); _PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; _PictureBox1.TabIndex = 43; _PictureBox1.TabStop = false; @@ -1544,40 +1548,40 @@ namespace ImageCatalog // ComboBox5 // ComboBox5.DataBindings.Add(new Binding("Text", bindingSource1, "LogoVerticalPosition", true, DataSourceUpdateMode.OnPropertyChanged)); - ComboBox5.Location = new Point(312, 413); + ComboBox5.Location = new Point(288, 387); ComboBox5.Margin = new Padding(6, 8, 6, 8); ComboBox5.Name = "ComboBox5"; - ComboBox5.Size = new Size(204, 40); + ComboBox5.Size = new Size(189, 38); ComboBox5.TabIndex = 42; ComboBox5.Text = "ComboBox5"; // // ComboBox4 // ComboBox4.DataBindings.Add(new Binding("Text", bindingSource1, "LogoHorizontalPosition", true, DataSourceUpdateMode.OnPropertyChanged)); - ComboBox4.Location = new Point(312, 355); + ComboBox4.Location = new Point(288, 333); ComboBox4.Margin = new Padding(6, 8, 6, 8); ComboBox4.Name = "ComboBox4"; - ComboBox4.Size = new Size(204, 40); + ComboBox4.Size = new Size(189, 38); ComboBox4.TabIndex = 41; ComboBox4.Text = "ComboBox4"; // // TextBox19 // TextBox19.DataBindings.Add(new Binding("Text", bindingSource1, "LogoTransparency", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox19.Location = new Point(312, 237); + TextBox19.Location = new Point(288, 222); TextBox19.Margin = new Padding(6, 8, 6, 8); TextBox19.Name = "TextBox19"; - TextBox19.Size = new Size(204, 39); + TextBox19.Size = new Size(189, 35); TextBox19.TabIndex = 40; TextBox19.Text = "TextBox19"; // // Label28 // Label28.ForeColor = Color.Black; - Label28.Location = new Point(37, 238); + Label28.Location = new Point(34, 223); Label28.Margin = new Padding(6, 0, 6, 0); Label28.Name = "Label28"; - Label28.Size = new Size(260, 40); + Label28.Size = new Size(240, 38); Label28.TabIndex = 39; Label28.Text = "Trasparenza (0-100%)"; Label28.TextAlign = ContentAlignment.MiddleLeft; @@ -1586,30 +1590,30 @@ namespace ImageCatalog // CheckBox5.DataBindings.Add(new Binding("Checked", bindingSource1, "AddLogo", true, DataSourceUpdateMode.OnPropertyChanged)); CheckBox5.ForeColor = Color.Black; - CheckBox5.Location = new Point(0, 64); + CheckBox5.Location = new Point(0, 60); CheckBox5.Margin = new Padding(6, 8, 6, 8); CheckBox5.Name = "CheckBox5"; - CheckBox5.Size = new Size(156, 50); + CheckBox5.Size = new Size(144, 47); CheckBox5.TabIndex = 38; CheckBox5.Text = "Aggiungi"; // // TextBox15 // TextBox15.DataBindings.Add(new Binding("Text", bindingSource1, "LogoHeight", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox15.Location = new Point(312, 178); + TextBox15.Location = new Point(288, 167); TextBox15.Margin = new Padding(6, 8, 6, 8); TextBox15.Name = "TextBox15"; - TextBox15.Size = new Size(204, 39); + TextBox15.Size = new Size(189, 35); TextBox15.TabIndex = 19; TextBox15.Text = "TextBox15"; // // TextBox14 // TextBox14.DataBindings.Add(new Binding("Text", bindingSource1, "LogoWidth", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox14.Location = new Point(312, 118); + TextBox14.Location = new Point(288, 111); TextBox14.Margin = new Padding(6, 8, 6, 8); TextBox14.Name = "TextBox14"; - TextBox14.Size = new Size(204, 39); + TextBox14.Size = new Size(189, 35); TextBox14.TabIndex = 18; TextBox14.Text = "TextBox14"; // @@ -1617,10 +1621,10 @@ namespace ImageCatalog // Label25.AutoSize = true; Label25.ForeColor = Color.Black; - Label25.Location = new Point(37, 413); + Label25.Location = new Point(34, 387); Label25.Margin = new Padding(6, 0, 6, 0); Label25.Name = "Label25"; - Label25.Size = new Size(210, 32); + Label25.Size = new Size(183, 30); Label25.TabIndex = 36; Label25.Text = "Posizione verticale"; Label25.TextAlign = ContentAlignment.MiddleLeft; @@ -1628,10 +1632,10 @@ namespace ImageCatalog // TextBox16 // TextBox16.DataBindings.Add(new Binding("Text", bindingSource1, "LogoMargin", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox16.Location = new Point(312, 296); + TextBox16.Location = new Point(288, 278); TextBox16.Margin = new Padding(6, 8, 6, 8); TextBox16.Name = "TextBox16"; - TextBox16.Size = new Size(204, 39); + TextBox16.Size = new Size(189, 35); TextBox16.TabIndex = 35; TextBox16.Text = "TextBox16"; // @@ -1639,10 +1643,10 @@ namespace ImageCatalog // Label24.AutoSize = true; Label24.ForeColor = Color.Black; - Label24.Location = new Point(41, 302); + Label24.Location = new Point(38, 283); Label24.Margin = new Padding(6, 0, 6, 0); Label24.Name = "Label24"; - Label24.Size = new Size(203, 32); + Label24.Size = new Size(176, 30); Label24.TabIndex = 34; Label24.Text = "Margine (pixel/%)"; Label24.TextAlign = ContentAlignment.MiddleLeft; @@ -1651,10 +1655,10 @@ namespace ImageCatalog // Label22.AutoSize = true; Label22.ForeColor = Color.Black; - Label22.Location = new Point(41, 125); + Label22.Location = new Point(38, 117); Label22.Margin = new Padding(6, 0, 6, 0); Label22.Name = "Label22"; - Label22.Size = new Size(90, 32); + Label22.Size = new Size(81, 30); Label22.TabIndex = 20; Label22.Text = "Altezza"; Label22.TextAlign = ContentAlignment.MiddleLeft; @@ -1663,30 +1667,30 @@ namespace ImageCatalog // Label23.AutoSize = true; Label23.ForeColor = Color.Black; - Label23.Location = new Point(41, 184); + Label23.Location = new Point(38, 172); Label23.Margin = new Padding(6, 0, 6, 0); Label23.Name = "Label23"; - Label23.Size = new Size(120, 32); + Label23.Size = new Size(107, 30); Label23.TabIndex = 21; Label23.Text = "Larghezza"; Label23.TextAlign = ContentAlignment.MiddleLeft; // // _Button4 // - _Button4.Location = new Point(1006, 59); + _Button4.Location = new Point(929, 55); _Button4.Margin = new Padding(6, 8, 6, 8); _Button4.Name = "_Button4"; - _Button4.Size = new Size(52, 50); + _Button4.Size = new Size(48, 47); _Button4.TabIndex = 8; _Button4.Text = "..."; // // TextBox10 // TextBox10.DataBindings.Add(new Binding("Text", bindingSource1, "LogoFile", true, DataSourceUpdateMode.OnPropertyChanged)); - TextBox10.Location = new Point(312, 59); + TextBox10.Location = new Point(288, 55); TextBox10.Margin = new Padding(6, 8, 6, 8); TextBox10.Name = "TextBox10"; - TextBox10.Size = new Size(672, 39); + TextBox10.Size = new Size(621, 35); TextBox10.TabIndex = 6; TextBox10.Text = "TextBox10"; // @@ -1694,10 +1698,10 @@ namespace ImageCatalog // Label29.AutoSize = true; Label29.ForeColor = Color.Black; - Label29.Location = new Point(37, 362); + Label29.Location = new Point(34, 339); Label29.Margin = new Padding(6, 0, 6, 0); Label29.Name = "Label29"; - Label29.Size = new Size(238, 32); + Label29.Size = new Size(208, 30); Label29.TabIndex = 36; Label29.Text = "Posizione orizzontale"; Label29.TextAlign = ContentAlignment.MiddleLeft; @@ -1706,10 +1710,10 @@ namespace ImageCatalog // Label30.AutoSize = true; Label30.ForeColor = Color.Black; - Label30.Location = new Point(41, 499); + Label30.Location = new Point(38, 468); Label30.Margin = new Padding(6, 0, 6, 0); Label30.Name = "Label30"; - Label30.Size = new Size(211, 32); + Label30.Size = new Size(184, 30); Label30.TabIndex = 36; Label30.Text = "Colore trasparente"; Label30.TextAlign = ContentAlignment.MiddleLeft; @@ -1718,20 +1722,20 @@ namespace ImageCatalog // PictureBox3 // PictureBox3.BorderStyle = BorderStyle.FixedSingle; - PictureBox3.Location = new Point(468, 472); + PictureBox3.Location = new Point(432, 442); PictureBox3.Margin = new Padding(6, 8, 6, 8); PictureBox3.Name = "PictureBox3"; - PictureBox3.Size = new Size(49, 56); + PictureBox3.Size = new Size(45, 53); PictureBox3.TabIndex = 44; PictureBox3.TabStop = false; PictureBox3.Visible = false; // // _Label27 // - _Label27.Location = new Point(1280, 931); + _Label27.Location = new Point(1182, 873); _Label27.Margin = new Padding(6, 0, 6, 0); _Label27.Name = "_Label27"; - _Label27.Size = new Size(304, 50); + _Label27.Size = new Size(281, 47); _Label27.TabIndex = 62; _Label27.Text = "Versione 2.2 2021"; _Label27.TextAlign = ContentAlignment.MiddleRight; @@ -1741,10 +1745,10 @@ namespace ImageCatalog _Button7.DataBindings.Add(new Binding("Enabled", bindingSource1, "UiDisabled", true, DataSourceUpdateMode.OnPropertyChanged)); _Button7.DataBindings.Add(new Binding("Command", bindingSource1, "AsyncCancelOperationCommand", true)); _Button7.Font = new Font("Microsoft Sans Serif", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 0); - _Button7.Location = new Point(1168, 296); + _Button7.Location = new Point(1078, 278); _Button7.Margin = new Padding(6, 8, 6, 8); _Button7.Name = "_Button7"; - _Button7.Size = new Size(416, 99); + _Button7.Size = new Size(384, 93); _Button7.TabIndex = 61; _Button7.Text = "STOP"; // @@ -1752,10 +1756,10 @@ namespace ImageCatalog // _Button5.DataBindings.Add(new Binding("Enabled", bindingSource1, "UiEnabled", true)); _Button5.Font = new Font("Microsoft Sans Serif", 11F, FontStyle.Bold, GraphicsUnit.Point, 0); - _Button5.Location = new Point(1168, 101); + _Button5.Location = new Point(1078, 95); _Button5.Margin = new Padding(6, 8, 6, 8); _Button5.Name = "_Button5"; - _Button5.Size = new Size(416, 78); + _Button5.Size = new Size(384, 73); _Button5.TabIndex = 60; _Button5.Text = "Salva impostazioni"; // @@ -1763,10 +1767,10 @@ namespace ImageCatalog // Label20.AutoSize = true; Label20.Font = new Font("Microsoft Sans Serif", 9.75F, FontStyle.Bold, GraphicsUnit.Point, 0); - Label20.Location = new Point(1168, 723); + Label20.Location = new Point(1078, 678); Label20.Margin = new Padding(6, 0, 6, 0); Label20.Name = "Label20"; - Label20.Size = new Size(183, 30); + Label20.Size = new Size(175, 29); Label20.TabIndex = 59; Label20.Text = "foto generate:"; // @@ -1774,10 +1778,10 @@ namespace ImageCatalog // Label19.AutoSize = true; Label19.Font = new Font("Microsoft Sans Serif", 9.75F, FontStyle.Bold, GraphicsUnit.Point, 0); - Label19.Location = new Point(1168, 677); + Label19.Location = new Point(1078, 635); Label19.Margin = new Padding(6, 0, 6, 0); Label19.Name = "Label19"; - Label19.Size = new Size(143, 30); + Label19.Size = new Size(135, 29); Label19.TabIndex = 58; Label19.Text = "foto totali: "; // @@ -1785,10 +1789,10 @@ namespace ImageCatalog // Label18.AutoSize = true; Label18.Font = new Font("Microsoft Sans Serif", 12F, FontStyle.Bold, GraphicsUnit.Point, 0); - Label18.Location = new Point(1393, 723); + Label18.Location = new Point(1286, 678); Label18.Margin = new Padding(6, 0, 6, 0); Label18.Name = "Label18"; - Label18.Size = new Size(36, 37); + Label18.Size = new Size(31, 32); Label18.TabIndex = 57; Label18.Text = "0"; // @@ -1796,20 +1800,20 @@ namespace ImageCatalog // lblFotoTotaliNum.AutoSize = true; lblFotoTotaliNum.Font = new Font("Microsoft Sans Serif", 12F, FontStyle.Bold, GraphicsUnit.Point, 0); - lblFotoTotaliNum.Location = new Point(1393, 677); + lblFotoTotaliNum.Location = new Point(1286, 635); lblFotoTotaliNum.Margin = new Padding(6, 0, 6, 0); lblFotoTotaliNum.Name = "lblFotoTotaliNum"; - lblFotoTotaliNum.Size = new Size(36, 37); + lblFotoTotaliNum.Size = new Size(31, 32); lblFotoTotaliNum.TabIndex = 56; lblFotoTotaliNum.Text = "0"; // // Label10 // Label10.Font = new Font("Microsoft Sans Serif", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 0); - Label10.Location = new Point(1168, 402); + Label10.Location = new Point(1078, 377); Label10.Margin = new Padding(6, 0, 6, 0); Label10.Name = "Label10"; - Label10.Size = new Size(416, 178); + Label10.Size = new Size(384, 167); Label10.TabIndex = 55; Label10.Text = "file"; // @@ -1817,10 +1821,10 @@ namespace ImageCatalog // _Button6.DataBindings.Add(new Binding("Enabled", bindingSource1, "UiEnabled", true)); _Button6.Font = new Font("Microsoft Sans Serif", 11F, FontStyle.Bold, GraphicsUnit.Point, 0); - _Button6.Location = new Point(1168, 24); + _Button6.Location = new Point(1078, 22); _Button6.Margin = new Padding(6, 8, 6, 8); _Button6.Name = "_Button6"; - _Button6.Size = new Size(416, 78); + _Button6.Size = new Size(384, 73); _Button6.TabIndex = 54; _Button6.Text = "Carica impostazioni"; // @@ -1828,10 +1832,10 @@ namespace ImageCatalog // _btnCreaCatalogoAsync.DataBindings.Add(new Binding("Enabled", bindingSource1, "UiEnabled", true)); _btnCreaCatalogoAsync.Font = new Font("Microsoft Sans Serif", 8.25F, FontStyle.Bold, GraphicsUnit.Point, 0); - _btnCreaCatalogoAsync.Location = new Point(1168, 187); + _btnCreaCatalogoAsync.Location = new Point(1078, 175); _btnCreaCatalogoAsync.Margin = new Padding(6, 8, 6, 8); _btnCreaCatalogoAsync.Name = "_btnCreaCatalogoAsync"; - _btnCreaCatalogoAsync.Size = new Size(416, 93); + _btnCreaCatalogoAsync.Size = new Size(384, 87); _btnCreaCatalogoAsync.TabIndex = 68; _btnCreaCatalogoAsync.Text = "CREA"; _btnCreaCatalogoAsync.UseVisualStyleBackColor = true; @@ -1840,11 +1844,29 @@ namespace ImageCatalog // dataModelBindingSource1.DataSource = typeof(ImageCatalog_2.DataModel); // + // btnOpenSourceFolder + // + btnOpenSourceFolder.Location = new Point(939, 38); + btnOpenSourceFolder.Margin = new Padding(6, 8, 6, 8); + btnOpenSourceFolder.Name = "btnOpenSourceFolder"; + btnOpenSourceFolder.Size = new Size(48, 35); + btnOpenSourceFolder.TabIndex = 26; + btnOpenSourceFolder.Text = "Apri"; + // + // btnOpenDestFolder + // + btnOpenDestFolder.Location = new Point(939, 97); + btnOpenDestFolder.Margin = new Padding(6, 8, 6, 8); + btnOpenDestFolder.Name = "btnOpenDestFolder"; + btnOpenDestFolder.Size = new Size(48, 35); + btnOpenDestFolder.TabIndex = 27; + btnOpenDestFolder.Text = "Apri"; + // // MainForm // - AutoScaleDimensions = new SizeF(13F, 32F); + AutoScaleDimensions = new SizeF(12F, 30F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(1601, 987); + ClientSize = new Size(1478, 925); Controls.Add(_btnCreaCatalogoAsync); Controls.Add(ProgressBar1); Controls.Add(CheckBox22); @@ -2255,6 +2277,8 @@ namespace ImageCatalog private Button button1; private NumericUpDown numericUpDown1; private NumericUpDown numericUpDown2; + private Button btnOpenDestFolder; + private Button btnOpenSourceFolder; internal Button btnCreaCatalogoAsync { diff --git a/imagecatalog/MainForm.cs b/imagecatalog/MainForm.cs index c5e7b12..d31a157 100644 --- a/imagecatalog/MainForm.cs +++ b/imagecatalog/MainForm.cs @@ -7,6 +7,7 @@ using System.Drawing.Text; using System.IO; using System.Linq; using System.Reflection; +using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -47,6 +48,10 @@ public partial class MainForm BindControls(); + // Wire up 'Open folder in Explorer' buttons + btnOpenSourceFolder.Click += BtnOpenSourceFolder_Click; + btnOpenDestFolder.Click += BtnOpenDestFolder_Click; + var version = Assembly.GetExecutingAssembly().GetName().Version; _Label27.Text = $"Version: {version.Major}.{version.Minor}.{version.Build}.{version.Revision}"; } @@ -70,6 +75,21 @@ public partial class MainForm Model.SaveSettingsRequested += OnSaveSettingsRequested; Model.LoadSettingsRequested += OnLoadSettingsRequested; Model.SelectColorRequested += OnSelectColorRequested; + // Show message requests (from ViewModel validation) + Model.ShowMessageRequested += OnShowMessageRequested; + } + + private void OnShowMessageRequested(object? sender, Tuple args) + { + if (args is null) return; + // Ensure call on UI thread + if (InvokeRequired) + { + Invoke(new Action(() => OnShowMessageRequested(sender, args))); + return; + } + + MessageBox.Show(this, args.Item1, args.Item2, MessageBoxButtons.OK, args.Item3); } private void SetDefaults() @@ -181,6 +201,57 @@ public partial class MainForm } } + private void BtnOpenSourceFolder_Click(object? sender, EventArgs e) + { + // Prefer the model value but fall back to the textbox if needed + var path = string.IsNullOrWhiteSpace(Model.SourcePath) ? txtSorgente.Text : Model.SourcePath; + OpenFolder(path); + } + + private void BtnOpenDestFolder_Click(object? sender, EventArgs e) + { + var path = string.IsNullOrWhiteSpace(Model.DestinationPath) ? txtDestinazione.Text : Model.DestinationPath; + OpenFolder(path); + } + + private void OpenFolder(string? path) + { + if (string.IsNullOrWhiteSpace(path)) + { + MessageBox.Show(this, "Folder path is empty.", "Open Folder", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + + path = path.Trim().Trim('"'); + + try + { + if (File.Exists(path)) + { + // If a file was provided, open its folder and select it + Process.Start("explorer.exe", $"/select,\"{path}\""); + return; + } + + if (Directory.Exists(path)) + { + Process.Start(new ProcessStartInfo + { + FileName = path, + UseShellExecute = true + }); + return; + } + + MessageBox.Show(this, $"Folder does not exist: {path}", "Open Folder", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + catch (Exception ex) + { + _logger?.LogError(ex, "Failed to open folder {Path}", path); + MessageBox.Show(this, $"Failed to open folder: {ex.Message}", "Open Folder", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + private void OnSelectDestinationFolderRequested(object sender, EventArgs e) { var dialogResult = SelectFolder(Model.DestinationPath); diff --git a/run-benchmarks.ps1 b/run-benchmarks.ps1 new file mode 100644 index 0000000..a228423 --- /dev/null +++ b/run-benchmarks.ps1 @@ -0,0 +1,124 @@ +# Image Processing Benchmark Runner +# This script provides easy access to common benchmark scenarios + +param( + [Parameter(Position=0)] + [ValidateSet("all", "quick", "parallel", "chunks", "sizes", "stress", "help")] + [string]$Scenario = "help", + + [switch]$Fast, + [switch]$DetailedOutput +) + +$projectPath = "MaddoShared.Benchmarks" + +function Show-Help { + Write-Host @" +Image Processing Benchmark Runner +================================== + +Usage: .\run-benchmarks.ps1 [scenario] [-Fast] [-DetailedOutput] + +Scenarios: + all - Run all benchmarks (60-120 minutes) + quick - Fast test run for development (5-10 minutes) + parallel - Test parallel processing strategies (20-30 minutes) + chunks - Optimize chunk size (20-30 minutes) + sizes - Test different image sizes (45-90 minutes) + stress - Large-scale stress test (2-4 hours) + help - Show this help message + +Flags: + -Fast - Use dry run for faster but less accurate results + -DetailedOutput - Show detailed output + +Examples: + .\run-benchmarks.ps1 quick + .\run-benchmarks.ps1 parallel -Fast + .\run-benchmarks.ps1 stress -DetailedOutput + +Results will be saved to: MaddoShared.Benchmarks\BenchmarkDotNet.Artifacts\results\ +"@ +} + +function Run-Benchmark { + param( + [string]$Filter, + [string]$Description + ) + + Write-Host "`n========================================" -ForegroundColor Cyan + Write-Host " $Description" -ForegroundColor Cyan + Write-Host "========================================`n" -ForegroundColor Cyan + + $args = @("-c", "Release") + + if ($Filter) { + $args += @("--", "--filter", $Filter) + } + + # Note: We don't pass --job arguments anymore because they override + # the InProcess toolchain configuration needed for Windows compatibility + if ($Fast) { + Write-Host "Note: Fast mode (-Fast) requested but not using --job dry" -ForegroundColor Yellow + Write-Host "Reason: --job arguments override InProcess toolchain config" -ForegroundColor Yellow + Write-Host "The benchmark will run with the default InProcessConfig settings.`n" -ForegroundColor Yellow + } + + if ($DetailedOutput) { + $args += "--verbosity", "detailed" + } + + Push-Location $projectPath + try { + dotnet run @args + } + finally { + Pop-Location + } +} + +# Main execution +switch ($Scenario) { + "help" { + Show-Help + } + + "all" { + Write-Host "Running ALL benchmarks..." -ForegroundColor Yellow + Write-Host "This will take 60-120 minutes. Press Ctrl+C to cancel.`n" -ForegroundColor Yellow + Start-Sleep -Seconds 3 + Run-Benchmark "" "All Benchmarks" + } + + "quick" { + Write-Host "Running QUICK test..." -ForegroundColor Green + Run-Benchmark "*ImageProcessingBenchmarks*" "Quick Development Test" + } + + "parallel" { + Write-Host "Running PARALLEL processing benchmarks..." -ForegroundColor Green + Run-Benchmark "*ImageProcessingBenchmarks*" "Parallel Processing Strategies" + } + + "chunks" { + Write-Host "Running CHUNK SIZE optimization..." -ForegroundColor Green + Run-Benchmark "*ChunkSizeBenchmarks*" "Chunk Size Optimization" + } + + "sizes" { + Write-Host "Running IMAGE SIZE comparison..." -ForegroundColor Green + Run-Benchmark "*ImageSizeBenchmarks*" "Image Size Impact Analysis" + } + + "stress" { + Write-Host "Running STRESS TEST..." -ForegroundColor Red + Write-Host "WARNING: This will take 2-4 hours and use significant disk space!" -ForegroundColor Red + Write-Host "Press Ctrl+C within 5 seconds to cancel...`n" -ForegroundColor Red + Start-Sleep -Seconds 5 + Run-Benchmark "*StressTestBenchmark*" "Large-Scale Stress Test" + } +} + +Write-Host "`nBenchmark execution complete!" -ForegroundColor Green +Write-Host "Results saved to: $projectPath\BenchmarkDotNet.Artifacts\results\" -ForegroundColor Green diff --git a/run-benchmarks.sh b/run-benchmarks.sh new file mode 100644 index 0000000..e9cc03a --- /dev/null +++ b/run-benchmarks.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +# Image Processing Benchmark Runner (Linux/Mac) +# This script provides easy access to common benchmark scenarios + +show_help() { + cat << EOF +Image Processing Benchmark Runner +================================== + +Usage: ./run-benchmarks.sh [scenario] [--fast] [--verbose] + +Scenarios: + all - Run all benchmarks (60-120 minutes) + quick - Fast test run for development (5-10 minutes) + parallel - Test parallel processing strategies (20-30 minutes) + chunks - Optimize chunk size (20-30 minutes) + sizes - Test different image sizes (45-90 minutes) + stress - Large-scale stress test (2-4 hours) + help - Show this help message + +Flags: + --fast - Use dry run for faster but less accurate results + --verbose - Show detailed output + +Examples: + ./run-benchmarks.sh quick + ./run-benchmarks.sh parallel --fast + ./run-benchmarks.sh stress --verbose + +Results will be saved to: MaddoShared.Benchmarks/BenchmarkDotNet.Artifacts/results/ +EOF +} + +run_benchmark() { + local filter=$1 + local description=$2 + + echo "" + echo "========================================" + echo " $description" + echo "========================================" + echo "" + + local args="-c Release" + + if [ -n "$filter" ]; then + args="$args -- --filter \"$filter\"" + fi + + if [ "$fast_mode" = true ]; then + args="$args --job dry" + fi + + if [ "$verbose_mode" = true ]; then + args="$args --verbose" + fi + + cd MaddoShared.Benchmarks + eval "dotnet run $args" + cd .. +} + +# Parse arguments +scenario="${1:-help}" +fast_mode=false +verbose_mode=false + +shift +while [ $# -gt 0 ]; do + case "$1" in + --fast) + fast_mode=true + ;; + --verbose) + verbose_mode=true + ;; + esac + shift +done + +# Main execution +case "$scenario" in + help) + show_help + ;; + + all) + echo "Running ALL benchmarks..." + echo "This will take 60-120 minutes. Press Ctrl+C to cancel." + echo "" + sleep 3 + run_benchmark "" "All Benchmarks" + ;; + + quick) + echo "Running QUICK test..." + run_benchmark "*ImageProcessingBenchmarks*" "Quick Development Test" + ;; + + parallel) + echo "Running PARALLEL processing benchmarks..." + run_benchmark "*ImageProcessingBenchmarks*" "Parallel Processing Strategies" + ;; + + chunks) + echo "Running CHUNK SIZE optimization..." + run_benchmark "*ChunkSizeBenchmarks*" "Chunk Size Optimization" + ;; + + sizes) + echo "Running IMAGE SIZE comparison..." + run_benchmark "*ImageSizeBenchmarks*" "Image Size Impact Analysis" + ;; + + stress) + echo "Running STRESS TEST..." + echo "WARNING: This will take 2-4 hours and use significant disk space!" + echo "Press Ctrl+C within 5 seconds to cancel..." + echo "" + sleep 5 + run_benchmark "*StressTestBenchmark*" "Large-Scale Stress Test" + ;; + + *) + echo "Unknown scenario: $scenario" + echo "Run './run-benchmarks.sh help' for usage information" + exit 1 + ;; +esac + +echo "" +echo "Benchmark execution complete!" +echo "Results saved to: MaddoShared.Benchmarks/BenchmarkDotNet.Artifacts/results/"