eienmojiki's picture
Update Gradio app with multiple files
c5900d7 verified
import gradio as gr
import cv2
import numpy as np
from registry import registry
from filters import *
from components import create_filter_controls
def create_app():
with gr.Blocks(theme=gr.themes.Soft(), css="""
.gradio-container {
max-width: 1600px !important;
margin: auto !important;
}
.filter-header {
text-align: center;
padding: 30px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 15px;
margin-bottom: 30px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
.filter-header h1 {
color: white !important;
margin: 0;
font-size: 2.5em;
font-weight: bold;
}
.filter-header p {
color: rgba(255,255,255,0.95) !important;
margin: 10px 0 0 0;
font-size: 1.1em;
}
.filter-header a {
color: rgba(255,255,255,0.9) !important;
text-decoration: none;
font-weight: 500;
transition: all 0.3s ease;
}
.filter-header a:hover {
color: white !important;
text-decoration: underline;
}
.image-container {
border-radius: 12px;
padding: 15px;
transition: all 0.3s ease;
}
.image-container:hover {
transform: translateY(-2px);
}
.control-panel {
border-radius: 12px;
padding: 20px;
margin-top: 15px;
}
.filter-description {
padding: 15px;
border-radius: 8px;
margin: 15px 0;
border-left: 4px solid #667eea;
}
.gr-button-primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
border: none !important;
font-weight: bold !important;
color: white !important;
transition: all 0.3s ease !important;
}
.gr-button-primary:hover {
transform: translateY(-2px) !important;
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4) !important;
}
.gr-button-secondary {
transition: all 0.3s ease !important;
}
.gr-button-secondary:hover {
transform: translateY(-2px) !important;
}
.stats-panel {
border-radius: 8px;
padding: 15px;
margin-top: 10px;
text-align: center;
}
/* Dark mode compatibility */
.dark .filter-description {
background: rgba(255,255,255,0.05);
}
.dark .image-container {
background: rgba(255,255,255,0.02);
}
.dark .control-panel {
background: rgba(255,255,255,0.03);
}
/* Light mode */
.filter-description {
background: #f0f4f8;
}
.image-container {
background: rgba(0,0,0,0.02);
}
.control-panel {
background: linear-gradient(to bottom, #f8f9fa, #ffffff);
}
""") as app:
# Header
with gr.Column(elem_classes="filter-header"):
gr.Markdown("""
# 📷 Photo Filter App
Professional photo editing with powerful filters - Fast & Easy
Built with [anycoder](https://huggingface.co/spaces/akhaliq/anycoder)
""")
# Initialize components
filter_names = list(registry.filters.keys())
# Top Row - Images side by side
with gr.Row():
# Left Column - Input Image
with gr.Column(scale=1):
with gr.Group(elem_classes="image-container"):
input_image = gr.Image(
label="📤 Original Image",
type="numpy",
height=500
)
# Right Column - Output Image
with gr.Column(scale=1):
with gr.Group(elem_classes="image-container"):
output_image = gr.Image(
label="✅ Edited Image",
height=500
)
error_message = gr.Markdown(visible=False)
with gr.Row():
download_button = gr.Button(
"💾 Download",
visible=False,
size="lg"
)
# Action Buttons
with gr.Row():
apply_button = gr.Button(
"✨ Apply Filter",
variant="primary",
size="lg",
scale=2
)
reset_button = gr.Button(
"🔄 Reset",
variant="secondary",
size="lg",
scale=1
)
# Bottom Row - Filter Selection & Parameters
with gr.Row():
with gr.Column(scale=1):
with gr.Group(elem_classes="control-panel"):
gr.Markdown("### 🎨 Select Filter")
filter_select = gr.Dropdown(
label="Filter",
choices=filter_names,
value="Original",
interactive=True
)
filter_doc = gr.Markdown(
value="Select a filter to see detailed description.",
elem_classes="filter-description"
)
with gr.Column(scale=1):
with gr.Group(elem_classes="control-panel"):
gr.Markdown("### ⚙️ Customize")
# Create dynamic filter controls
filter_controls, control_components = create_filter_controls()
# Stats panel
with gr.Row():
with gr.Column():
gr.Markdown(
f"""
<div class="stats-panel">
📊 <b>Total Filters:</b> {len(filter_names)} |
🎯 <b>Parameterized Filters:</b> {sum(1 for f in filter_names if registry.params_map.get(f))} |
🚀 <b>Quick Filters:</b> {sum(1 for f in filter_names if not registry.params_map.get(f))}
</div>
"""
)
# Handle UI updates
def update_controls(filter_name):
updates = []
for group_name in filter_controls:
updates.append(gr.update(visible=group_name == filter_name))
doc = registry.filters[filter_name].__doc__ or "No detailed description available."
return updates + [doc]
# Handle image processing
def process(image, filter_name, *args):
if image is None:
return None, gr.update(visible=True, value="⚠️ **Note:** Please upload an image before applying filters!"), gr.update(visible=False)
try:
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# Get parameters for current filter
params = {}
if filter_name in control_components:
param_names = list(registry.params_map.get(filter_name, {}).keys())
controls_list = control_components[filter_name]
for i, param_name in enumerate(param_names):
if i < len(controls_list):
params[param_name] = args[i]
processed = registry.filters[filter_name](image, **params)
if len(processed.shape) == 2:
processed = cv2.cvtColor(processed, cv2.COLOR_GRAY2RGB)
else:
processed = cv2.cvtColor(processed, cv2.COLOR_BGR2RGB)
return processed, gr.update(visible=False), gr.update(visible=True)
except Exception as e:
return None, gr.update(visible=True, value=f"❌ **Error:** {str(e)}"), gr.update(visible=False)
# Handle reset
def reset_all():
return None, None, gr.update(visible=False), gr.update(visible=False), "Original"
# Collect all control components
all_control_components = []
for filter_name in control_components:
all_control_components.extend(control_components[filter_name])
# Connect events
filter_select.change(
update_controls,
inputs=filter_select,
outputs=list(filter_controls.values()) + [filter_doc],
api_name=False
)
input_components = [input_image, filter_select] + all_control_components
apply_button.click(
process,
inputs=input_components,
outputs=[output_image, error_message, download_button],
)
reset_button.click(
reset_all,
inputs=None,
outputs=[input_image, output_image, error_message, download_button, filter_select]
)
return app
if __name__ == "__main__":
app = create_app()
app.launch()