eienmojiki's picture
Update Gradio app with multiple files
c5900d7 verified
raw
history blame
9.46 kB
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()