Daniel251's picture
Update app.py
7ffc770 verified
Raw
History Blame Contribute Delete
10.2 kB
"""
🎨 Basic Image Adjustments - App 2 do Photoshop AI Ecosystem
Versão otimizada para Hugging Face Spaces com Gradio 6.2.0
"""
import gradio as gr
from PIL import Image, ImageEnhance, ImageOps
import tempfile
import numpy as np
import sys
print("=" * 50)
print("🚀 INICIANDO APP BASIC ADJUSTMENTS")
print(f"Python version: {sys.version}")
print(f"Gradio version: {gr.__version__}")
print(f"PIL version: {Image.__version__}")
print("=" * 50)
# ========== FUNÇÕES DE PROCESSAMENTO ==========
def process_image(image, brightness=1.0, contrast=1.0, saturation=1.0, sharpness=1.0, auto_contrast=False):
"""Aplica ajustes básicos à imagem"""
try:
if image is None:
return None
# Converter para PIL Image se necessário
if isinstance(image, np.ndarray):
img = Image.fromarray(image.astype('uint8'))
elif isinstance(image, dict) and 'image' in image:
img = Image.fromarray(image['image'])
else:
img = image
# Converter para RGB se necessário
if img.mode != 'RGB':
img = img.convert('RGB')
# Aplicar contraste automático
if auto_contrast:
img = ImageOps.autocontrast(img, cutoff=2)
# Aplicar ajustes
if brightness != 1.0:
img = ImageEnhance.Brightness(img).enhance(brightness)
if contrast != 1.0:
img = ImageEnhance.Contrast(img).enhance(contrast)
if saturation != 1.0:
img = ImageEnhance.Color(img).enhance(saturation)
if sharpness != 1.0:
img = ImageEnhance.Sharpness(img).enhance(sharpness)
return img
except Exception as e:
print(f"❌ ERRO em process_image: {str(e)}")
return None
def get_preset(preset_name):
"""Retorna valores para os presets"""
presets = {
'vibrant': (1.2, 1.3, 1.4, 1.1, False),
'soft': (1.05, 0.9, 0.8, 0.9, False),
'dramatic': (0.9, 1.4, 0.9, 1.3, False),
'retro': (1.0, 1.1, 0.6, 1.0, False),
'bw': (1.0, 1.2, 0.0, 1.1, False),
'reset': (1.0, 1.0, 1.0, 1.0, False)
}
return presets.get(preset_name, presets['reset'])
def save_image(image):
"""Salva imagem para download"""
try:
if image is None:
return None
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png", prefix="adjusted_")
image.save(temp_file.name, "PNG", optimize=True)
return temp_file.name
except Exception as e:
print(f"❌ ERRO em save_image: {str(e)}")
return None
def update_on_load(image):
"""Atualiza displays quando imagem é carregada"""
if image is None:
return None, None
processed = process_image(image)
return image, processed
def update_on_change(image, b, c, s, sh, ac):
"""Atualiza imagem quando controles mudam"""
if image is None:
return None
return process_image(image, b, c, s, sh, ac)
# ========== INTERFACE GRADIO ==========
with gr.Blocks(title="🎨 Basic Image Adjustments") as demo:
# Cabeçalho
gr.HTML("""
<div style="text-align: center; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 10px; color: white; margin-bottom: 20px;">
<h1 style="margin: 0; font-size: 2.2em;">🎨 Basic Image Adjustments</h1>
<p style="margin: 5px 0 0 0; opacity: 0.9; font-size: 1.1em;">App 2 do Photoshop AI Ecosystem</p>
<p style="margin: 5px 0 0 0; font-size: 0.95em;">Ajuste brilho, contraste, saturação e nitidez em tempo real</p>
</div>
""")
with gr.Row():
# Coluna 1: Upload e Controles
with gr.Column(scale=1):
gr.Markdown("### 📤 Upload da Imagem")
image_input = gr.Image(
type="pil",
label="Clique ou arraste uma imagem aqui",
height=180
)
gr.Markdown("### ⚙️ Controles de Ajuste")
with gr.Group():
brightness = gr.Slider(
minimum=0.0,
maximum=2.0,
value=1.0,
step=0.1,
label="☀️ Brilho",
info="Controla a luminosidade geral"
)
contrast = gr.Slider(
minimum=0.0,
maximum=2.0,
value=1.0,
step=0.1,
label="🎭 Contraste",
info="Controla a diferença entre cores"
)
saturation = gr.Slider(
minimum=0.0,
maximum=2.0,
value=1.0,
step=0.1,
label="🌈 Saturação",
info="Controla a intensidade das cores"
)
sharpness = gr.Slider(
minimum=0.0,
maximum=2.0,
value=1.0,
step=0.1,
label="🔍 Nitidez",
info="Controla a definição dos detalhes"
)
auto_contrast = gr.Checkbox(
label="⚡ Contraste Automático",
value=False,
info="Otimiza automaticamente o contraste"
)
# Coluna 2: Presets e Visualização
with gr.Column(scale=1):
gr.Markdown("### 🎨 Presets Rápidos")
with gr.Row():
vibrant_btn = gr.Button("✨ Vibrante", size="sm")
soft_btn = gr.Button("🌸 Suave", size="sm")
dramatic_btn = gr.Button("🌑 Dramático", size="sm")
with gr.Row():
retro_btn = gr.Button("📻 Retrô", size="sm")
bw_btn = gr.Button("⚫ P&B", size="sm")
reset_btn = gr.Button("🔄 Resetar", size="sm")
gr.Markdown("### 👁️ Visualização")
with gr.Row():
with gr.Column():
gr.Markdown("**Original**")
original_display = gr.Image(
type="pil",
interactive=False,
height=220,
show_label=False
)
with gr.Column():
gr.Markdown("**Ajustada**")
processed_display = gr.Image(
type="pil",
interactive=False,
height=220,
show_label=False
)
# Download
with gr.Row():
with gr.Column():
gr.Markdown("### 💾 Exportar Imagem")
download_btn = gr.Button(
"📥 Baixar Imagem Ajustada",
variant="primary",
size="lg"
)
download_file = gr.File(
label="Arquivo para download",
interactive=False
)
# ========== EVENTOS ==========
# Quando imagem é carregada
image_input.change(
fn=update_on_load,
inputs=[image_input],
outputs=[original_display, processed_display]
)
# Quando controles mudam
controls = [brightness, contrast, saturation, sharpness, auto_contrast]
for control in controls:
control.change(
fn=update_on_change,
inputs=[image_input] + controls,
outputs=[processed_display]
)
# Presets
vibrant_btn.click(
fn=lambda: get_preset('vibrant'),
outputs=controls
)
soft_btn.click(
fn=lambda: get_preset('soft'),
outputs=controls
)
dramatic_btn.click(
fn=lambda: get_preset('dramatic'),
outputs=controls
)
retro_btn.click(
fn=lambda: get_preset('retro'),
outputs=controls
)
bw_btn.click(
fn=lambda: get_preset('bw'),
outputs=controls
)
reset_btn.click(
fn=lambda: get_preset('reset'),
outputs=controls
)
# Download
download_btn.click(
fn=save_image,
inputs=[processed_display],
outputs=[download_file]
)
# Guia de uso
with gr.Accordion("📖 Guia de Uso & Dicas", open=False):
gr.Markdown("""
## 🚀 Como usar:
1. **Upload** da imagem
2. **Ajuste** os controles deslizantes
3. **Use presets** para efeitos rápidos
4. **Compare** original vs ajustada
5. **Baixe** o resultado
## 💡 Dicas por tipo de foto:
**Retratos**: Brilho 1.05, Contraste 1.1, Saturação 0.9
**Paisagens**: Brilho 1.1, Contraste 1.2, Saturação 1.2
**Produtos**: Brilho 1.0, Contraste 1.3, Nitidez 1.2
## 🎨 Presets:
- **Vibrante**: Cores intensas para natureza
- **Suave**: Tons delicados para retratos
- **Dramático**: Alto contraste
- **Retrô**: Efeito vintage
- **P&B**: Preto e branco
""")
# Rodapé
gr.HTML(f"""
<div style="text-align: center; margin-top: 30px; padding: 15px; background: #f8f9fa; border-radius: 8px;">
<p style="margin: 0; font-weight: bold;">🎨 Basic Image Adjustments - Photoshop AI Ecosystem</p>
<p style="margin: 5px 0 0 0; font-size: 0.9em; color: #666;">
Gradio {gr.__version__} • Python {sys.version.split()[0]}
</p>
</div>
""")
print("✅ Interface criada com sucesso")
print("🏁 App pronto para Hugging Face Spaces")
# Launch explícito para Hugging Face Spaces
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
show_error=True
)