Spaces:
Runtime error
Runtime error
| #!/usr/bin/python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| UI components construction for IC-Custom application. | |
| """ | |
| import gradio as gr | |
| from constants import ( | |
| ASPECT_RATIO_LABELS, | |
| DEFAULT_ASPECT_RATIO, | |
| DEFAULT_BRUSH_SIZE | |
| ) | |
| def create_theme(): | |
| """Create and configure the Gradio theme.""" | |
| theme = gr.themes.Ocean() | |
| theme.set( | |
| checkbox_label_background_fill_selected="*button_primary_background_fill", | |
| checkbox_label_text_color_selected="*button_primary_text_color", | |
| ) | |
| return theme | |
| def create_css(): | |
| """Create custom CSS for the application.""" | |
| from stylesheets import get_css | |
| return get_css() | |
| def create_header_section(): | |
| """Create the header section with title and description.""" | |
| from metainfo import head, getting_started | |
| with gr.Row(): | |
| gr.HTML(head) | |
| with gr.Accordion(label="π Getting Started:", open=True, elem_id="accordion"): | |
| with gr.Row(equal_height=True): | |
| gr.HTML(getting_started) | |
| def create_customization_section(): | |
| """Create the customization mode selection section.""" | |
| with gr.Row(): | |
| # Add a note to remind users to click Clear before starting | |
| md_custmization_mode = gr.Markdown( | |
| "1. Select a Customization Mode\n\n*Tip: Please click the Clear button first to reset all states before starting a new task.*" | |
| ) | |
| with gr.Row(): | |
| custmization_mode = gr.Radio( | |
| ["Position-aware", "Position-free"], | |
| value="Position-aware", | |
| scale=1, | |
| elem_id="customization_mode_radio", | |
| show_label=False, | |
| label="Customization Mode", | |
| ) | |
| return custmization_mode, md_custmization_mode | |
| def create_image_input_section(): | |
| """Create image input section optimized for left column layout.""" | |
| # Reference image section | |
| md_image_reference = gr.Markdown("2. Input reference image") | |
| with gr.Group(): | |
| image_reference = gr.Image( | |
| label="Reference Image", | |
| type="pil", | |
| interactive=True, | |
| height=320, | |
| container=True, | |
| elem_id="reference_image" | |
| ) | |
| # Input mask mode selection | |
| md_input_mask_mode = gr.Markdown("3. Select input mask mode") | |
| with gr.Group(): | |
| input_mask_mode = gr.Radio( | |
| ["Precise mask", "User-drawn mask"], | |
| value="Precise mask", | |
| elem_id="input_mask_mode_radio", | |
| show_label=False, | |
| label="Input Mask Mode", | |
| ) | |
| # Target image section | |
| md_target_image = gr.Markdown("4. Input target image & mask (Iterate clicking or brushing until the target is covered)") | |
| # Precise mask mode | |
| with gr.Group(): | |
| image_target_1 = gr.Image( | |
| type="pil", | |
| label="Target Image (precise mask)", | |
| interactive=True, | |
| visible=True, | |
| height=500, | |
| container=True, | |
| elem_id="target_image_1" | |
| ) | |
| with gr.Row(): | |
| undo_target_seg_button = gr.Button( | |
| 'Undo seg', | |
| elem_id="undo_btnSEG", | |
| visible=True, | |
| size="sm", | |
| scale=1 | |
| ) | |
| # User-drawn mask mode | |
| with gr.Group(): | |
| image_target_2 = gr.ImageEditor( | |
| label="Target Image (user-drawn mask)", | |
| type="pil", | |
| brush=gr.Brush(colors=["#FFFFFF"], default_size=DEFAULT_BRUSH_SIZE, color_mode="fixed"), | |
| layers=False, | |
| interactive=True, | |
| sources=["upload", "clipboard"], | |
| placeholder="Please click here or the icon to upload the image.", | |
| visible=False, | |
| height=500, | |
| container=True, | |
| elem_id="target_image_2", | |
| fixed_canvas=True, | |
| ) | |
| return (image_reference, input_mask_mode, image_target_1, image_target_2, | |
| undo_target_seg_button, md_image_reference, md_input_mask_mode, md_target_image) | |
| def create_prompt_section(): | |
| """Create the text prompt input section with improved layout.""" | |
| md_prompt = gr.Markdown("5. Input text prompt (optional)") | |
| with gr.Group(): | |
| prompt = gr.Textbox( | |
| placeholder="Please input the description for the target scene.", | |
| value="", | |
| lines=2, | |
| show_label=False, | |
| label="Text Prompt", | |
| container=True, | |
| elem_id="text_prompt" | |
| ) | |
| with gr.Row(): | |
| vlm_generate_btn = gr.Button( | |
| "π€ VLM Auto-generate", | |
| scale=1, | |
| elem_id="vlm_generate_btn", | |
| variant="secondary" | |
| ) | |
| vlm_polish_btn = gr.Button( | |
| "β¨ VLM Auto-polish", | |
| scale=1, | |
| elem_id="vlm_polish_btn", | |
| variant="secondary" | |
| ) | |
| return prompt, vlm_generate_btn, vlm_polish_btn, md_prompt | |
| def create_advanced_options_section(): | |
| """Create the advanced options section.""" | |
| with gr.Accordion("Advanced Options", open=False, elem_id="accordion1"): | |
| with gr.Group(): | |
| aspect_ratio = gr.Dropdown( | |
| label="Output aspect ratio", | |
| choices=ASPECT_RATIO_LABELS, | |
| value=DEFAULT_ASPECT_RATIO, | |
| interactive=True, | |
| allow_custom_value=False, | |
| filterable=False, | |
| elem_id="aspect_ratio_dropdown" | |
| ) | |
| with gr.Group(): | |
| seg_ref_mode = gr.Radio( | |
| label="Segmentation mode", | |
| choices=["Full Ref", "Masked Ref"], | |
| value="Full Ref", | |
| elem_id="seg_ref_mode_radio" | |
| ) | |
| move_to_center = gr.Checkbox(label="Move object to center", value=False, elem_id="move_to_center_checkbox") | |
| with gr.Group(): | |
| with gr.Row(): | |
| use_background_preservation = gr.Checkbox(label="Use background preservation", value=False, elem_id="use_bg_preservation_checkbox") | |
| background_blend_threshold = gr.Slider( | |
| label="Background blend threshold", | |
| minimum=0, | |
| maximum=1, | |
| step=0.1, | |
| value=0.5 | |
| ) | |
| with gr.Group(): | |
| with gr.Row(): | |
| seed = gr.Slider( | |
| label="Seed (-1 for random): ", | |
| minimum=-1, | |
| maximum=2147483647, | |
| step=1, | |
| value=-1, | |
| scale=4 | |
| ) | |
| num_images_per_prompt = gr.Slider( | |
| label="Num samples", | |
| minimum=1, | |
| maximum=4, | |
| step=1, | |
| value=1, | |
| scale=1 | |
| ) | |
| with gr.Group(): | |
| with gr.Row(): | |
| guidance = gr.Slider( | |
| label="Guidance scale", | |
| minimum=10, | |
| maximum=65, | |
| step=1, | |
| value=40, | |
| ) | |
| num_steps = gr.Slider( | |
| label="Number of inference steps", | |
| minimum=1, | |
| maximum=60, | |
| step=1, | |
| value=32, | |
| ) | |
| with gr.Row(): | |
| true_gs = gr.Slider( | |
| label="True GS", | |
| minimum=1, | |
| maximum=10, | |
| step=1, | |
| value=3, | |
| ) | |
| return (aspect_ratio, seg_ref_mode, move_to_center, use_background_preservation, | |
| background_blend_threshold, seed, num_images_per_prompt, guidance, num_steps, true_gs) | |
| def create_mask_operation_section(): | |
| """Create mask operation section optimized for right column (outputs).""" | |
| md_mask_operation = gr.Markdown("6. View or modify the target mask") | |
| with gr.Group(): | |
| # Mask gallery with responsive layout | |
| mask_gallery = gr.Gallery( | |
| label='Mask Preview', | |
| show_label=False, | |
| interactive=False, | |
| columns=2, | |
| rows=1, | |
| height="auto", | |
| object_fit="contain", | |
| preview=True, | |
| allow_preview=True, | |
| selected_index=0, | |
| elem_id="mask_gallery", | |
| elem_classes=["custom-gallery", "responsive-gallery"], | |
| container=True, | |
| show_fullscreen_button=False | |
| ) | |
| # Mask operation buttons - horizontal layout | |
| with gr.Row(): | |
| dilate_button = gr.Button( | |
| 'π Dilate', | |
| elem_id="dilate_btn", | |
| variant="secondary", | |
| size="sm", | |
| scale=1 | |
| ) | |
| erode_button = gr.Button( | |
| 'π½ Erode', | |
| elem_id="erode_btn", | |
| variant="secondary", | |
| size="sm", | |
| scale=1 | |
| ) | |
| bounding_box_button = gr.Button( | |
| 'π¦ Bounding box', | |
| elem_id="bounding_box_btn", | |
| variant="secondary", | |
| size="sm", | |
| scale=1 | |
| ) | |
| return mask_gallery, dilate_button, erode_button, bounding_box_button, md_mask_operation | |
| def create_output_section(): | |
| """Create the output section optimized for right column.""" | |
| md_submit = gr.Markdown("7. Submit and view the output") | |
| # Generation controls at top for better workflow | |
| with gr.Group(): | |
| with gr.Row(): | |
| submit_button = gr.Button( | |
| "π« Generate", | |
| variant="primary", | |
| scale=3, | |
| size="lg" | |
| ) | |
| clear_btn = gr.ClearButton( | |
| scale=1, | |
| variant="secondary", | |
| value="ποΈ Clear" | |
| ) | |
| # Results gallery with responsive layout | |
| with gr.Group(): | |
| result_gallery = gr.Gallery( | |
| label='Generated Results', | |
| show_label=False, | |
| interactive=False, | |
| columns=1, | |
| rows=1, | |
| height="auto", | |
| object_fit="contain", | |
| preview=True, | |
| allow_preview=True, | |
| selected_index=0, | |
| elem_id="result_gallery", | |
| elem_classes=["custom-gallery", "responsive-gallery"], | |
| container=True, | |
| show_fullscreen_button=False | |
| ) | |
| return result_gallery, submit_button, clear_btn, md_submit | |
| def create_examples_section(examples_list, inputs, outputs, fn): | |
| """Create the examples section with required arguments.""" | |
| examples = gr.Examples( | |
| examples=examples_list, | |
| inputs=inputs, | |
| outputs=outputs, | |
| fn=fn, | |
| cache_examples=False, | |
| examples_per_page=10, | |
| run_on_click=True, | |
| ) | |
| return examples | |
| def create_citation_section(): | |
| """Create the citation section.""" | |
| from metainfo import citation | |
| with gr.Row(): | |
| gr.Markdown(citation) | |