Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| def render_sidebar(reset_generation_state): | |
| st.sidebar.title("Navigation") | |
| app_page = st.sidebar.radio( | |
| "Go to Page:", | |
| [ | |
| "๐จ Image-to-SVG Vectorizer", | |
| "๐ ๏ธ Tool Extract", | |
| "โก Interactive Node Simplifier" | |
| ] | |
| ) | |
| # Only show controls on vectorizer page | |
| if app_page == "๐จ Image-to-SVG Vectorizer": | |
| st.sidebar.header("โ๏ธ Adjustment Controls") | |
| # ---------------------------------------------------------------- | |
| # 1. DEFINE PRESET TEMPLATES & OPTIONS | |
| # ---------------------------------------------------------------- | |
| # Add "Custom" to the options list | |
| quality_options = [ | |
| "High (Detailed)", | |
| "Moderate (Balanced)", | |
| "Low (Blurry/Sketchy)", | |
| "Custom" | |
| ] | |
| # Preset values maps | |
| presets = { | |
| "High (Detailed)": {"scale_val": 2.5, "canny_low_val": 5, "canny_high_val": 40}, | |
| "Moderate (Balanced)": {"scale_val": 2.0, "canny_low_val": 10, "canny_high_val": 70}, | |
| "Low (Blurry/Sketchy)": {"scale_val": 1.2, "canny_low_val": 40, "canny_high_val": 150} | |
| } | |
| # Initialize session state variables safely on first run | |
| if "quality_val" not in st.session_state: | |
| st.session_state.quality_val = "Moderate (Balanced)" | |
| if "scale_val" not in st.session_state: | |
| st.session_state.scale_val = 2.0 | |
| if "canny_low_val" not in st.session_state: | |
| st.session_state.canny_low_val = 10 | |
| if "canny_high_val" not in st.session_state: | |
| st.session_state.canny_high_val = 70 | |
| # ---------------------------------------------------------------- | |
| # 2. CALLBAK FUNCTIONS FOR STATE MANAGEMENT | |
| # ---------------------------------------------------------------- | |
| def on_preset_change(): | |
| """Triggered when the user changes the dropdown explicitly.""" | |
| reset_generation_state() | |
| selected = st.session_state.quality_val | |
| # If they chose a real template, force-apply those values | |
| if selected in presets: | |
| st.session_state.scale_val = presets[selected]["scale_val"] | |
| st.session_state.canny_low_val = presets[selected]["canny_low_val"] | |
| st.session_state.canny_high_val = presets[selected]["canny_high_val"] | |
| def on_slider_change(): | |
| """Triggered when user tweaks any preset-controlled slider.""" | |
| reset_generation_state() | |
| # If they move a slider, flip the dropdown automatically to 'Custom' | |
| st.session_state.quality_val = "Custom" | |
| # ---------------------------------------------------------------- | |
| # 3. QUALITY PRESET DROPDOWN | |
| # ---------------------------------------------------------------- | |
| current_quality = st.session_state.quality_val | |
| idx = quality_options.index(current_quality) if current_quality in quality_options else 1 | |
| st.sidebar.selectbox( | |
| "Extraction Quality Preset", | |
| quality_options, | |
| index=idx, | |
| key="quality_val", | |
| on_change=on_preset_change | |
| ) | |
| # ---------------------------------------------------------------- | |
| # 4. IMAGE CLEAN-UP | |
| # ---------------------------------------------------------------- | |
| st.sidebar.subheader("Image Clean-up") | |
| st.sidebar.slider( | |
| "De-blur (Sharpening)", | |
| 0.0, 3.0, | |
| key="sharpen_val", | |
| step=0.1, | |
| on_change=reset_generation_state # Independent slider | |
| ) | |
| st.sidebar.slider( | |
| "Resize Scale", | |
| 1.0, 3.0, | |
| key="scale_val", | |
| step=0.1, | |
| on_change=on_slider_change # Auto-switches preset to Custom | |
| ) | |
| # ---------------------------------------------------------------- | |
| # 5. BACKGROUND REMOVAL (GRABCUT) | |
| # ---------------------------------------------------------------- | |
| st.sidebar.subheader("โ๏ธ Background Removal") | |
| enable_grabcut = st.sidebar.checkbox( | |
| "Isolate Foreground Object", | |
| key="enable_grabcut", | |
| help="Uses the GrabCut algorithm to eliminate background noise before vectorization.", | |
| on_change=reset_generation_state | |
| ) | |
| if enable_grabcut: | |
| st.sidebar.slider( | |
| "Background Crop Margin", | |
| 1, 50, | |
| key="bbox_padding", | |
| step=1, | |
| help="Tells the algorithm how close the object is to the image edges (in pixels).", | |
| on_change=reset_generation_state | |
| ) | |
| else: | |
| st.session_state.bbox_padding = 10 | |
| # ---------------------------------------------------------------- | |
| # 6. EDGE SETTINGS (CONTAINS PRESET TARGET SLIDERS) | |
| # ---------------------------------------------------------------- | |
| st.sidebar.subheader("๐ Thresholding & Outlines") | |
| st.sidebar.slider( | |
| "Canny Low Threshold", | |
| 5, 100, | |
| key="canny_low_val", | |
| on_change=on_slider_change # Auto-switches preset to Custom | |
| ) | |
| st.sidebar.slider( | |
| "Canny High Threshold", | |
| 30, 250, | |
| key="canny_high_val", | |
| on_change=on_slider_change # Auto-switches preset to Custom | |
| ) | |
| # ---------------------------------------------------------------- | |
| # 7. LINE STYLE | |
| # ---------------------------------------------------------------- | |
| st.sidebar.subheader("๐๏ธ Line Styling") | |
| skeletonize = st.sidebar.checkbox( | |
| "Skeletonize (Single-Pixel Path)", | |
| key="skeletonize_val", | |
| on_change=reset_generation_state | |
| ) | |
| if not skeletonize: | |
| st.sidebar.slider( | |
| "Contour Thickness", | |
| 1, 5, | |
| key="contour_thickness_val", | |
| on_change=reset_generation_state | |
| ) | |
| st.sidebar.slider( | |
| "Line Thicken (Dilate)", | |
| 0, 3, | |
| key="dilate_iter_val", | |
| on_change=reset_generation_state | |
| ) | |
| else: | |
| st.session_state.contour_thickness_val = 1 | |
| st.session_state.dilate_iter_val = 0 | |
| return app_page |