From 6b10806b16e74b269d4253652231c96fbcf0222f Mon Sep 17 00:00:00 2001 From: arys Date: Mon, 12 Jan 2026 11:37:42 +0500 Subject: [PATCH] fix --- .../service/MarketingStrategyService.java | 62 +++++++++++++------ .../NanoBananaImageGenerationService.java | 19 +++--- 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java b/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java index 9563c5f..aa94e00 100644 --- a/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java +++ b/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java @@ -289,12 +289,29 @@ public class MarketingStrategyService { if (optAnalysis.isPresent()) { MarketingAnalysis analysis = optAnalysis.get(); StringBuilder businessContext = new StringBuilder(); - if (analysis.getBusinessNiche() != null) { - businessContext.append("Ниша бизнеса: ").append(analysis.getBusinessNiche()).append(". "); + + if (analysis.getProduct() != null && !analysis.getProduct().isEmpty()) { + businessContext.append("Главный объект изображения (продукт): ").append(analysis.getProduct()).append(". "); } - if (analysis.getProduct() != null) { - businessContext.append("Продукт: ").append(analysis.getProduct()).append("."); + + if (analysis.getBusinessNiche() != null && !analysis.getBusinessNiche().isEmpty()) { + businessContext.append("Ниша: ").append(analysis.getBusinessNiche()).append(". "); } + + if (analysis.getTargetAudience() != null) { + Map ta = analysis.getTargetAudience(); + if (ta.containsKey("ageRanges") || ta.containsKey("types")) { + businessContext.append("Целевая аудитория (люди на фото): "); + if (ta.containsKey("types")) { + businessContext.append(ta.get("types")).append(" "); + } + if (ta.containsKey("ageRanges")) { + businessContext.append("возраст ").append(ta.get("ageRanges")); + } + businessContext.append(". "); + } + } + return businessContext.toString(); } } catch (Exception e) { @@ -504,14 +521,13 @@ public class MarketingStrategyService { private void generateAndSaveImageForPost(MarketingStrategy.PostCalendarItem item, String businessContext) { try { - // Create prompt for image generation String imagePrompt = buildImagePrompt(item, businessContext); - // Generate image + logger.info("Generating image with prompt: {}", imagePrompt); + byte[] imageBytes = imageGenerationService.generateImage(imagePrompt); if (imageBytes != null && imageBytes.length > 0) { - // Save image to MinIO String filename = "post_image_" + System.currentTimeMillis() + "_" + item.hashCode() + ".png"; minIOService.uploadFile(filename, imageBytes, MediaType.IMAGE_PNG.toString()); @@ -531,26 +547,36 @@ public class MarketingStrategyService { private String buildImagePrompt(MarketingStrategy.PostCalendarItem item, String businessContext) { StringBuilder prompt = new StringBuilder(); - prompt.append("Создай привлекательное маркетинговое изображение для поста в социальных сетях. "); + String style = "высококачественная фотография, реалистичное освещение, 8k, высокая детализация"; + if (item.getPlatform() != null) { + String platform = item.getPlatform().toLowerCase(); + if (platform.contains("linkedin")) { + style += ", корпоративный стиль, профессионально, минимализм, чисто"; + } else if (platform.contains("instagram") || platform.contains("tiktok")) { + style += ", лайфстайл, эстетика, яркие цвета, привлекательно, инстаграм-стиль"; + } else if (platform.contains("facebook")) { + style += ", уютно, дружелюбно, для сообщества"; + } + } + + prompt.append("Фотореалистичное изображение. "); + + // Добавляем контекст продукта (это самое важное!) if (businessContext != null && !businessContext.isEmpty()) { prompt.append(businessContext).append(" "); } + // 3. Контекст поста if (item.getTheme() != null && !item.getTheme().isEmpty()) { - prompt.append("Тема поста: ").append(item.getTheme()).append(". "); + prompt.append("Сюжет изображения: ").append(item.getTheme()).append(". "); } - if (item.getPostText() != null && !item.getPostText().isEmpty()) { - // Use first 100 characters of post text for context - String textPreview = item.getPostText().length() > 100 - ? item.getPostText().substring(0, 100) + "..." - : item.getPostText(); - prompt.append("Текст поста: ").append(textPreview).append(". "); - } + prompt.append("Композиция: продукт или услуга в центре внимания. "); + prompt.append("Если на фото есть люди, они должны взаимодействовать с продуктом естественно. "); + prompt.append("Избегать: абстрактных концепций, людей с планшетами смотрящих в камеру, искусственных поз, текста на изображении, размытия, искажений. "); - prompt.append("Стиль: современный, профессиональный, привлекающий внимание, подходящий для социальных сетей. "); - prompt.append("Изображение должно быть ярким, но не перегруженным, с акцентом на главную идею поста."); + prompt.append("Визуальный стиль: ").append(style).append("."); return prompt.toString(); } diff --git a/src/main/java/kz/konturai/parser/service/NanoBananaImageGenerationService.java b/src/main/java/kz/konturai/parser/service/NanoBananaImageGenerationService.java index b703356..f1c9cf9 100644 --- a/src/main/java/kz/konturai/parser/service/NanoBananaImageGenerationService.java +++ b/src/main/java/kz/konturai/parser/service/NanoBananaImageGenerationService.java @@ -87,8 +87,14 @@ public class NanoBananaImageGenerationService implements ImageGenerationService } String endpointUrl = String.format(VERTEX_API_TEMPLATE, location, projectId, location, model); - String enrichedPrompt = enrichPromptForGemini(prompt); - Map requestBody = buildImagenRequestBody(enrichedPrompt); + + + String finalPrompt = prompt; + if (prompt != null && prompt.length() < 50) { + finalPrompt = "High quality, photorealistic image of: " + prompt; + } + + Map requestBody = buildImagenRequestBody(finalPrompt); logger.info("Sending request to Vertex AI. Project: {}, Model: {}", projectId, model); @@ -150,9 +156,11 @@ public class NanoBananaImageGenerationService implements ImageGenerationService Map parameters = new HashMap<>(); parameters.put("sampleCount", 1); parameters.put("aspectRatio", "1:1"); + parameters.put("safetyFilterLevel", "block_some"); parameters.put("personGeneration", "allow_adult"); - parameters.put("negativePrompt", "nsfw, nudity, sexual content, lgbt symbols, rainbow flags, provocative clothing, violence, gore, blood, deformed, ugly, watermark, text, signature"); + + parameters.put("negativePrompt", "nsfw, nudity, sexual content, lgbt symbols, rainbow flags, provocative clothing, violence, gore, blood, deformed, ugly, watermark, text, signature, low quality, blurry, distorted, unrealistic"); body.put("parameters", parameters); return body; @@ -186,9 +194,4 @@ public class NanoBananaImageGenerationService implements ImageGenerationService .filter(t -> t instanceof WebClientResponseException && ((WebClientResponseException) t).getStatusCode().value() == 429); } - - private String enrichPromptForGemini(String original) { - return "Professional, high quality, photorealistic image of: " + original + - ". Style: neutral, business-appropriate, culturally respectful."; - } } \ No newline at end of file