""" 🎨 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("""

🎨 Basic Image Adjustments

App 2 do Photoshop AI Ecosystem

Ajuste brilho, contraste, saturação e nitidez em tempo real

""") 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"""

🎨 Basic Image Adjustments - Photoshop AI Ecosystem

Gradio {gr.__version__} • Python {sys.version.split()[0]}

""") 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 )