import gradio as gr import json import os from PIL import Image import tempfile # from utils.extractor import DesignTokenExtractor # from utils.token_generator import TokenCodeGenerator def create_token_preview(tokens): """Create HTML preview of extracted tokens""" html = """

Extracted Design Tokens

""" # Color palette preview if 'colors' in tokens and tokens['colors']: html += """

Colors

""" for name, color in tokens['colors'].items(): html += f"""
{name}
{color['hex']}
{int(color.get('proportion', 0) * 100)}%
""" html += "
" # Spacing preview if 'spacing' in tokens and tokens['spacing']: html += """

Spacing

""" for name, value in tokens['spacing'].items(): try: height = value.replace('px', '') html += f"""
{name}
{value}
""" except: pass html += "
" # Typography preview if 'typography' in tokens and tokens['typography']: html += """

Typography

""" for name, props in tokens['typography'].items(): size = props.get('size', '16px') weight = props.get('weight', '400') family = props.get('family', 'sans-serif') html += f"""
Sample {name.title()} Text
{family} • {size} • Weight {weight}
""" html += "
" html += "
" return html def process_screenshot(image, output_format, progress=None): """Process uploaded screenshot and extract design tokens""" if image is None: return None, "Please upload a screenshot", None # Temporary stub implementation for testing try: # Mock tokens for testing tokens = { "colors": { "primary": {"hex": "#3B82F6", "rgb": "rgb(59, 130, 246)", "proportion": 0.25}, "secondary": {"hex": "#8B5CF6", "rgb": "rgb(139, 92, 246)", "proportion": 0.15} }, "spacing": { "small": "8px", "medium": "16px", "large": "32px" }, "typography": { "heading": {"family": "sans-serif", "size": "32px", "weight": "700"}, "body": {"family": "sans-serif", "size": "16px", "weight": "400"} } } # Simple CSS output for testing code_output = ":root {\n --color-primary: #3B82F6;\n --color-secondary: #8B5CF6;\n --spacing-small: 8px;\n --spacing-medium: 16px;\n --spacing-large: 32px;\n}" # Save output file output_filename = "design_tokens.css" with open(output_filename, "w") as f: f.write(code_output) # Create preview visualization preview_html = create_token_preview(tokens) return preview_html, code_output, output_filename except Exception as e: return None, f"Error processing screenshot: {str(e)}", None def create_gradio_app(): """Create the main Gradio application""" with gr.Blocks( title="Design Token Extractor", theme=gr.themes.Soft(), css=""" .gradio-container { font-family: 'Inter', system-ui, sans-serif; } .gr-button-primary { background-color: #3b82f6 !important; } """ ) as app: gr.Markdown( """ # 🎨 Design Token Extractor Transform UI screenshots into structured design token libraries using AI-powered analysis. Upload a screenshot to automatically extract colors, spacing, typography, and component tokens. --- """ ) with gr.Row(): with gr.Column(scale=1): input_image = gr.Image( label="Upload UI Screenshot", type="pil", sources=["upload", "clipboard"], height=400 ) output_format = gr.Radio( choices=[ "CSS Variables", "Tailwind Config", "JSON Tokens", "Style Dictionary", "SCSS Variables" ], value="CSS Variables", label="Output Format", info="Choose the format for your design tokens" ) extract_btn = gr.Button( "🚀 Extract Design Tokens", variant="primary", size="lg" ) gr.Markdown( """ ### Tips for best results: - Use high-quality screenshots (min 800px width) - Include various UI elements for comprehensive extraction - Screenshots with clear color hierarchy work best - Ensure good contrast between elements """ ) with gr.Column(scale=1): preview = gr.HTML( label="Token Preview", value="
Upload a screenshot to see extracted tokens
" ) code_output = gr.Code( label="Generated Code", language="css", lines=20, value="// Your design tokens will appear here" ) download_file = gr.File( label="Download Tokens", visible=True ) # Examples section commented out until example images are available # gr.Markdown("### Example Screenshots") # gr.Examples( # examples=[ # ["examples/dashboard.png", "CSS Variables"], # ["examples/landing_page.png", "Tailwind Config"], # ["examples/mobile_app.png", "JSON Tokens"] # ], # inputs=[input_image, output_format], # cache_examples=False # ) # Connect the extraction function extract_btn.click( fn=process_screenshot, inputs=[input_image, output_format], outputs=[preview, code_output, download_file] ) # Add footer gr.Markdown( """ --- ### Features: - **Color Extraction**: Identifies dominant colors and creates semantic color roles - **Spacing Detection**: Analyzes layout patterns to extract consistent spacing values - **Typography Analysis**: Detects font styles and creates text hierarchy tokens - **Multiple Output Formats**: Export to CSS, Tailwind, JSON, Style Dictionary, or SCSS Built with ❤️ using Gradio and computer vision models """ ) return app if __name__ == "__main__": app = create_gradio_app() app.launch( server_name="0.0.0.0", server_port=7860, share=True, show_error=True )