From eb2b1a0ad7dd5df40423354a2fe34a155f1f87fd Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 16 Mar 2026 12:42:15 +0100 Subject: [PATCH 1/9] increase the limit --- GUI/logic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GUI/logic.py b/GUI/logic.py index 53ae2c4..1c8a8c2 100644 --- a/GUI/logic.py +++ b/GUI/logic.py @@ -135,7 +135,7 @@ def run_subprocess(): total_rows = len(rows) # Кількість фото за один запуск (безпечно для 16GB RAM) - chunk_size = 500 + chunk_size = 1000 total_chunks = math.ceil(total_rows / chunk_size) # 2. Перебираємо і запускаємо пакети по черзі From 4a10349992a698b6e427fb0cc85f6b6e019e3742 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 16 Mar 2026 12:48:36 +0100 Subject: [PATCH 2/9] remove batch processing --- GUI/logic.py | 52 ++++++++++------------------------------------------ 1 file changed, 10 insertions(+), 42 deletions(-) diff --git a/GUI/logic.py b/GUI/logic.py index 1c8a8c2..d90c424 100644 --- a/GUI/logic.py +++ b/GUI/logic.py @@ -13,7 +13,6 @@ path_exporting = "" - def get_base_dir(): """Визначає реальну папку, навіть якщо це скомпільований .exe""" if getattr(sys, 'frozen', False): @@ -127,48 +126,17 @@ def run_subprocess(): "creationflags": subprocess.CREATE_NO_WINDOW} if sys.platform == "win32" else {} try: - # 1. Читаємо оригінальний великий CSV файл - with open(path_csv, 'r', encoding='utf-8') as f: - reader = csv.reader(f) - header = next(reader) - rows = list(reader) - - total_rows = len(rows) - # Кількість фото за один запуск (безпечно для 16GB RAM) - chunk_size = 1000 - total_chunks = math.ceil(total_rows / chunk_size) - - # 2. Перебираємо і запускаємо пакети по черзі - for i in range(total_chunks): - chunk_rows = rows[i * chunk_size: (i + 1) * chunk_size] - - # Створюємо шлях до тимчасового файлу в тій самій папці - temp_csv = os.path.join(base_dir, f"temp_chunk_{i}.csv") - - with open(temp_csv, 'w', encoding='utf-8', newline='') as f: - writer = csv.writer(f) - writer.writerow(header) - writer.writerows(chunk_rows) - - # 3. Викликаємо C# ядро, передаючи йому ТИМЧАСОВИЙ файл замість основного! - result = subprocess.run( - [exe_path, temp_csv, path_config, path_template, path_exporting], - capture_output=True, text=True, **kwargs - ) - - # Одразу видаляємо шматок CSV, він нам більше не потрібен - if os.path.exists(temp_csv): - os.remove(temp_csv) - - # Якщо C# крашнувся на якомусь із пакетів - зупиняємо все і показуємо помилку - if result.returncode != 0: - messagebox.showerror(f"Error in batch file { - i+1}/{total_chunks}", result.stdout or result.stderr) - return - + result = subprocess.run( + [exe_path, path_csv, path_config, path_template, path_exporting], + capture_output=True, text=True, **kwargs + ) # 4. Якщо весь цикл пройшов без помилок - messagebox.showinfo("Success!", f"All { - total_rows} baners successfuly generated with batch files \n") + if result.returncode != 0: + messagebox.showerror( + "Error", f"Generator failed:\n{result.stderr}") + else: + messagebox.showinfo( + "Success!", "All baners successfuly generated with batch files \n") except Exception as e: messagebox.showerror("Critical Error", str(e)) From 8aad8ce3d84d0cecc87961ed381cb87c87440921 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 16 Mar 2026 14:39:18 +0100 Subject: [PATCH 3/9] remove collection --- Services/ImageBuilder.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Services/ImageBuilder.cs b/Services/ImageBuilder.cs index 7afcc3d..e6fff12 100644 --- a/Services/ImageBuilder.cs +++ b/Services/ImageBuilder.cs @@ -54,8 +54,6 @@ public static ConcurrentBag GenerateAll( try { // 1. Відкриваємо колекцію шарів - using (var collection = new MagickImageCollection(templateBytes)) - { // 2. Сплющуємо шари в одне фонове зображення using (var image = new MagickImage(collection[0])) { @@ -121,7 +119,6 @@ public static ConcurrentBag GenerateAll( image.Write(outputPath); } // Тут image знищується і звільняє пам'ять - } // Тут collection знищується // Логування успішного збереження int currentCount = System.Threading.Interlocked.Increment(ref processed); From 37ee28356cdb034f4251d86445cb6be75305221b Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 16 Mar 2026 14:41:28 +0100 Subject: [PATCH 4/9] reduce image quality and fix --- Services/ImageBuilder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Services/ImageBuilder.cs b/Services/ImageBuilder.cs index e6fff12..11d0774 100644 --- a/Services/ImageBuilder.cs +++ b/Services/ImageBuilder.cs @@ -55,7 +55,7 @@ public static ConcurrentBag GenerateAll( { // 1. Відкриваємо колекцію шарів // 2. Сплющуємо шари в одне фонове зображення - using (var image = new MagickImage(collection[0])) + using (var image = new MagickImage(templateBytes)) { // image.Density = new Density(72, 72); int imageWidth = (int)image.Width; // Беремо ширину для вирівнювання по центру @@ -115,7 +115,7 @@ public static ConcurrentBag GenerateAll( // Малюємо і зберігаємо ТУТ, поки image ще існує image.Format = MagickFormat.Avif; - image.Quality = 90; + image.Quality = 80; image.Write(outputPath); } // Тут image знищується і звільняє пам'ять From 2351cb09ea311121a690f4ef787df85a68ed7541 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 16 Mar 2026 14:43:40 +0100 Subject: [PATCH 5/9] remove bottlnecks --- Program.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Program.cs b/Program.cs index 734f691..f51ab0d 100644 --- a/Program.cs +++ b/Program.cs @@ -45,15 +45,9 @@ static void Main(string[] args) Console.WriteLine($"CSV: {csvPath} (Існує: {File.Exists(csvPath)})"); Console.WriteLine($"Config: {configPath} (Існує: {File.Exists(configPath)})"); Console.WriteLine($"Template: {templatePath} (Існує: {File.Exists(templatePath)})"); - Console.ReadLine(); return; } - Console.WriteLine("❌ Помилка: Не знайдено основні файли (config.json, data.csv або шаблон)!"); - Console.WriteLine($"CSV: {csvPath} (Існує: {File.Exists(csvPath)})"); - Console.WriteLine($"Config: {configPath} (Існує: {File.Exists(configPath)})"); - Console.WriteLine($"Template: {templatePath} (Існує: {File.Exists(templatePath)})"); - Directory.CreateDirectory(outputDir); // 1. Читання конфігу та CSV @@ -76,8 +70,6 @@ static void Main(string[] args) // 4. Формування звіту (Делегуємо сервісу) ReportService.GenerateReport(logs, reportPath); - Console.WriteLine("\nНатисніть Enter для виходу..."); - Console.ReadLine(); } } } From f444135b488e98446e688661bc3a439622cbbf5a Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 16 Mar 2026 14:50:44 +0100 Subject: [PATCH 6/9] remove the layers for psd --- Services/TemplateAnalyzer.cs | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/Services/TemplateAnalyzer.cs b/Services/TemplateAnalyzer.cs index 80cdf1e..07804d8 100644 --- a/Services/TemplateAnalyzer.cs +++ b/Services/TemplateAnalyzer.cs @@ -11,40 +11,11 @@ public static class TemplateAnalyzer public static (byte[] TemplateBytes, Dictionary Coords) Analyze(string templatePath, Dictionary config) { - byte[] templateBytes; - var dynamicCoords = new Dictionary(); + var dynamicCoords = new Dictionary(); - using (var collection = new MagickImageCollection(templatePath)) - { - if (collection.Count > 1) - { - for (int i = collection.Count - 1; i >= 1; i--) - { - var layer = collection[i]; - string layerName = layer.GetAttribute("label") ?? layer.Label; + byte[] templateBytes = File.ReadAllBytes(templatePath); - if (!string.IsNullOrEmpty(layerName)) - { - var match = config.FirstOrDefault(c => - layerName.Equals(c.Value.PsdLayer ?? c.Key, StringComparison.OrdinalIgnoreCase)); - if(match.Key != null) - { - dynamicCoords[match.Key] = (layer.Page.X, layer.Page.Y); - Console.WriteLine($" 📍 Координати для '{match.Key}': X={layer.Page.X}, Y={layer.Page.Y}"); - collection.RemoveAt(i); - } - } - } - collection.RemoveAt(0); - using var cleanBackground = collection.Flatten(); - templateBytes = cleanBackground.ToByteArray(); - } - else - { - templateBytes = collection[0].ToByteArray(); - } - } - return (templateBytes, dynamicCoords); + return (templateBytes, dynamicCoords); } } } From 70b5e6f905da92c51e217d5594d4005cff3b927e Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 16 Mar 2026 14:52:25 +0100 Subject: [PATCH 7/9] skip existing generated files --- Services/ImageBuilder.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Services/ImageBuilder.cs b/Services/ImageBuilder.cs index 11d0774..df602a2 100644 --- a/Services/ImageBuilder.cs +++ b/Services/ImageBuilder.cs @@ -23,11 +23,6 @@ public static ConcurrentBag GenerateAll( var logs = new ConcurrentBag(); int processed = 0; - int imageWidth; - using (var tempImage = new MagickImage(templateBytes)) - { - imageWidth = (int)tempImage.Width; - } Func threadsProcent = (x) => Math.Max(1, (int)(Environment.ProcessorCount * x )); @@ -51,6 +46,12 @@ public static ConcurrentBag GenerateAll( string outputPath = Path.Combine(outputDir, $"{filename}.avif"); + if(File.Exists(outputPath)) + { + logs.Add(new LogEntry(true, filename)); + return; + } + try { // 1. Відкриваємо колекцію шарів From 8a7945bb2e5134b8a95b85c36f3b5b08c247684e Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 16 Mar 2026 14:53:52 +0100 Subject: [PATCH 8/9] avif speed --- Services/ImageBuilder.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Services/ImageBuilder.cs b/Services/ImageBuilder.cs index df602a2..4a069b9 100644 --- a/Services/ImageBuilder.cs +++ b/Services/ImageBuilder.cs @@ -26,7 +26,7 @@ public static ConcurrentBag GenerateAll( Func threadsProcent = (x) => Math.Max(1, (int)(Environment.ProcessorCount * x )); - int safeThreads = threadsProcent(0.5); + int safeThreads = threadsProcent(0.75); if(config.TryGetValue("GLOBAL_SETTINGS", out var max_threads) && max_threads.MaxThreads.HasValue) { @@ -117,6 +117,7 @@ public static ConcurrentBag GenerateAll( // Малюємо і зберігаємо ТУТ, поки image ще існує image.Format = MagickFormat.Avif; image.Quality = 80; + image.Settings.SetDefine("avif:speed", "8"); image.Write(outputPath); } // Тут image знищується і звільняє пам'ять From 484d420c725f3cf9ca81afa1556f854d702fded3 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 16 Mar 2026 14:54:49 +0100 Subject: [PATCH 9/9] make better quality --- Services/ImageBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Services/ImageBuilder.cs b/Services/ImageBuilder.cs index 4a069b9..279a909 100644 --- a/Services/ImageBuilder.cs +++ b/Services/ImageBuilder.cs @@ -117,7 +117,7 @@ public static ConcurrentBag GenerateAll( // Малюємо і зберігаємо ТУТ, поки image ще існує image.Format = MagickFormat.Avif; image.Quality = 80; - image.Settings.SetDefine("avif:speed", "8"); + image.Settings.SetDefine("avif:speed", "6"); image.Write(outputPath); } // Тут image знищується і звільняє пам'ять