From 2087f3245b21871c0598913179fd8649b44a01e7 Mon Sep 17 00:00:00 2001 From: p <1332606303@qq.com> Date: Sat, 17 Jan 2026 16:51:34 +0800 Subject: [PATCH] feat: optimize prompt styles and refine image generation context logic --- backend/app/core/prompts.py | 28 ++++++++++++++-------------- backend/app/routers/generation.py | 28 ++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/backend/app/core/prompts.py b/backend/app/core/prompts.py index e380520..3b5f8d5 100644 --- a/backend/app/core/prompts.py +++ b/backend/app/core/prompts.py @@ -26,15 +26,15 @@ Behaviors and Rules: - 'type': 'comic_config' - 'language': 'English', - 'style': '{User Specified Style}' (Must fill in the user-specified style, if not specified, default to 'Chibi/Fantasy Style') - - 'bubble_style': { 'shape': 'Bubble Shape', 'color': 'Background Color', 'font_color': 'Font Color', 'stroke_width': 'Stroke Width' } - - 'narration_style': { 'shape': 'Box/Rounded', 'color': 'Background Color', 'font_color': 'Font Color', 'opacity': 'Opacity' } - - 'border_style': { 'width': 'Line Width', 'color': 'Color', 'type': 'Solid/Hand-drawn' } - - 'gutter_style': { 'type': 'Standard Cross Split', 'color': 'White', 'width': '10px' } + - 'bubble_style': { 'shape': 'Round/Cloud/Jagged', 'color': 'Hex Color Code or Standard Color Name', 'stroke_width': 'Pixel Value (e.g. 2px)', 'font': { 'color': 'Hex/Name', 'size': 'Pixel Value', 'family': 'Font Family Name' } } (Adjust based on story tone, e.g., Jagged for action/horror) + - 'narration_style': { 'shape': 'Rectangle/RoundedBox', 'color': 'Hex/Name', 'opacity': '0.0-1.0', 'font': { 'color': 'Hex/Name', 'size': 'Pixel Value', 'family': 'Font Name' } } (Adjust based on narrative voice) + - 'border_style': { 'color': 'Hex/Name', 'type': 'Solid/Rough/None', 'width': 'Pixel Value' } (Thicker/Rougher for intense stories) + - 'gutter_style': { 'color': 'Hex/Name', 'type': 'Standard', 'width': 'Pixel Value' } (Wider for slow pacing, narrower for fast action) - 'layout_settings': { - 'show_panel_numbers': false, // [Switch] Whether to show panel numbers - 'panel_number_style': { 'position': 'top-left', 'bg_color': '#000000', 'text_color': '#00FF41', 'font_size': '14px' }, + 'show_panel_numbers': false, + 'panel_number_style': { 'position': 'top-left', 'bg_color': 'Black', 'text_color': 'Neon Green', 'font_size': '14px' }, 'force_uniform_borders': true, - 'composition_mode': 'grid' // grid=Grid Splicing, cinematic=Cinematic Widescreen + 'composition_mode': 'grid' } - 'aspect_ratio': '16:9' @@ -47,13 +47,13 @@ Behaviors and Rules: - 'type': 'character_sheet' - 'name': 'Character Name' - 'meta_info':{ - - 'language': Language based on user input - - 'role': 'Protagonist' | 'Supporting' | 'Extra' (Must indicate character type) - - 'personality': 'Character personality traits, e.g., Cheerful, Cold, Hot-blooded, etc., which will affect expressions and poses' - - 'age': 'Age description, approximate range' - - 'relationships': 'Description of relationship with protagonist or other characters' (Must indicate interpersonal relationships) + - 'language': Language based on user input, + - 'role': 'Protagonist' | 'Supporting' | 'Extra' (Must indicate character type), + - 'personality': 'Character personality traits, e.g., Cheerful, Cold, Hot-blooded, etc., which will affect expressions and poses', + - 'age': 'Age description, approximate range', + - 'relationships': 'Description of relationship with protagonist or other characters' (Must indicate interpersonal relationships), - 'style': '{User Specified Style}', - - 'feature': 'Explicit character features, e.g., Youthful, Plump, etc.' + - 'feature': 'Explicit character features, e.g., Youthful, Plump, etc.', - 'aspect_ratio': '16:9' } - 'design_panels': [ @@ -76,7 +76,7 @@ Behaviors and Rules: 'style': '{User Specified Style}', 'language': 'English', 'volume': 'Current Volume/Total Volumes', - 'aspect_ratio': '16:9', + 'aspect_ratio': '16:9' } - 'characters': ['List of characters appearing in this group of panels'] - 'plot_breakdown': [ diff --git a/backend/app/routers/generation.py b/backend/app/routers/generation.py index ad6db0f..03b24db 100644 --- a/backend/app/routers/generation.py +++ b/backend/app/routers/generation.py @@ -231,11 +231,9 @@ def generate_storyboard_task(task_id: str, project_id: str, user_input: str): meta["aspect_ratio"] = global_aspect # Also inject specific style configs if present - if "bubble_style" in config_block: meta["bubble_style"] = config_block["bubble_style"] - if "narration_style" in config_block: meta["narration_style"] = config_block["narration_style"] - if "border_style" in config_block: meta["border_style"] = config_block["border_style"] - if "gutter_style" in config_block: meta["gutter_style"] = config_block["gutter_style"] - if "layout_settings" in config_block: meta["layout_settings"] = config_block["layout_settings"] + for key in ["bubble_style", "narration_style", "border_style", "gutter_style", "layout_settings"]: + if key in config_block: + meta[key] = config_block[key] block["meta_info"] = meta @@ -365,7 +363,10 @@ def generate_all_images_task(task_id: str, project_id: str): if os.path.exists(abs_path) and abs_path not in context_images: context_images.append(abs_path) - # b) Previous History (Last 3 logic) + # b) Previous History (Last 3 logic) - RE-ENABLED for Batch Generation + # For batch generation, we build history as we go. + # This ensures panel N is consistent with panel N-1. + if len(generated_history) >= 3: selected = [generated_history[0]] + generated_history[-2:] else: @@ -736,6 +737,8 @@ def generate_panel_task(task_id: str, item_id: int): base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # 1. Find Character Images + # STRICT POLICY: Only use the currently active character image (p_char.image_url). + # Do NOT search ImageHistory or other versions. This ensures consistency with the user's current selection. char_names = item.data.get("characters", []) if isinstance(char_names, str): char_names = [char_names] elif isinstance(char_names, list): @@ -754,12 +757,21 @@ def generate_panel_task(task_id: str, item_id: int): if os.path.exists(abs_path) and abs_path not in context_images: context_images.append(abs_path) - # 2. Previous Panels + # 2. Previous Panels - RE-ENABLED but with strict filtering + # We want to use PREVIOUSLY CONFIRMED panels as reference to maintain consistency, + # but NOT the current panel's old version (which we are regenerating). + # STRICT POLICY: Only use currently active panel images (i.image_url) from the database. + + # Filter logic: + # - Use panels with sequence number LESS than current item.sequence + # - Ensure they have an image_url (meaning they are generated/confirmed) + # - Limit to last 3 to keep context fresh but manageable + prev_items = sorted([i for i in project.storyboard_items if i.sequence < item.sequence and i.image_url], key=lambda x: x.sequence) if prev_items: selected = [] if len(prev_items) >= 3: - selected = [prev_items[0]] + prev_items[-2:] + selected = [prev_items[0]] + prev_items[-2:] # First one + last two else: selected = prev_items