import gradio as gr from PIL import Image import os import tempfile def optimize_image(image, png_optimize, jpeg_quality, jpeg_resolution, webp_quality): img = Image.open(image) original_size = os.path.getsize(image.name) / 1024 # tamaño en KB # Crear un directorio seguro para almacenar las imágenes optimizadas output_dir = "/tmp/optimized_images" os.makedirs(output_dir, exist_ok=True) # Generar archivos temporales en un directorio seguro lossless_output_path = os.path.join(output_dir, "lossless.png") lossy_output_path = os.path.join(output_dir, "lossy.jpg") reduced_output_path = os.path.join(output_dir, "reduced_resolution.jpg") webp_lossy_output_path = os.path.join(output_dir, "lossy.webp") # 1. Compresión sin pérdida (PNG) img.save(lossless_output_path, format="PNG", optimize=png_optimize) lossless_size = os.path.getsize(lossless_output_path) / 1024 lossless_diff = original_size - lossless_size lossless_img = Image.open(lossless_output_path) # 2. Compresión con pérdida (JPEG) img.save(lossy_output_path, format="JPEG", quality=jpeg_quality, optimize=True) lossy_size = os.path.getsize(lossy_output_path) / 1024 lossy_diff = original_size - lossy_size lossy_img = Image.open(lossy_output_path) # 3. Reducción de resolución (JPEG) new_resolution = (img.width * jpeg_resolution // 100, img.height * jpeg_resolution // 100) reduced_img = img.resize(new_resolution, Image.LANCZOS) reduced_img.save(reduced_output_path, format="JPEG", quality=jpeg_quality, optimize=True) reduced_size = os.path.getsize(reduced_output_path) / 1024 reduced_diff = original_size - reduced_size reduced_img = Image.open(reduced_output_path) # 4. Compresión con WebP (con pérdida) img.save(webp_lossy_output_path, format="WEBP", quality=webp_quality, optimize=True) webp_lossy_size = os.path.getsize(webp_lossy_output_path) / 1024 webp_lossy_diff = original_size - webp_lossy_size webp_lossy_img = Image.open(webp_lossy_output_path) # Retornar las imágenes optimizadas, tamaños y rutas para descarga return [ lossless_img, f"Sin pérdida: {lossless_size:.2f} KB (diferencia: {-lossless_diff:.2f} KB)", lossless_output_path, lossy_img, f"Con pérdida: {lossy_size:.2f} KB (diferencia: {-lossy_diff:.2f} KB)", lossy_output_path, reduced_img, f"Reducción de resolución: {reduced_size:.2f} KB (diferencia: {-reduced_diff:.2f} KB)", reduced_output_path, webp_lossy_img, f"WebP con pérdida: {webp_lossy_size:.2f} KB (diferencia: {-webp_lossy_diff:.2f} KB)", webp_lossy_output_path ] def download_image(file_path): return gr.File.update(value=file_path, label="Descargar", visible=True) with gr.Blocks() as demo: gr.Markdown("### Optimización de imágenes para la web") image_input = gr.File(label="Sube tu imagen", file_types=['image']) optimize_button = gr.Button("Optimizar") with gr.Row(): with gr.Column(): optimized_output1 = gr.Image(label="Optimización sin pérdida") png_optimize = gr.Checkbox(label="Optimizar PNG", value=True) optimized_size1 = gr.Text(value="", interactive=False, show_label=False) download_button1 = gr.Button("Descargar") download_file1 = gr.File(visible=False) with gr.Column(): optimized_output2 = gr.Image(label="Optimización con pérdida (JPEG)") jpeg_quality = gr.Slider(label="Calidad JPEG", minimum=10, maximum=100, value=50, step=1) optimized_size2 = gr.Text(value="", interactive=False, show_label=False) download_button2 = gr.Button("Descargar") download_file2 = gr.File(visible=False) with gr.Column(): optimized_output3 = gr.Image(label="Reducción de resolución (JPEG)") jpeg_resolution = gr.Slider(label="Resolución JPEG (%)", minimum=10, maximum=100, value=50, step=1) optimized_size3 = gr.Text(value="", interactive=False, show_label=False) download_button3 = gr.Button("Descargar") download_file3 = gr.File(visible=False) with gr.Column(): optimized_output4 = gr.Image(label="Optimización WebP con pérdida") webp_quality = gr.Slider(label="Calidad WebP", minimum=10, maximum=100, value=50, step=1) optimized_size4 = gr.Text(value="", interactive=False, show_label=False) download_button4 = gr.Button("Descargar") download_file4 = gr.File(visible=False) # Conectar cada control a la función de optimización optimize_button.click( fn=optimize_image, inputs=[image_input, png_optimize, jpeg_quality, jpeg_resolution, webp_quality], outputs=[ optimized_output1, optimized_size1, download_file1, optimized_output2, optimized_size2, download_file2, optimized_output3, optimized_size3, download_file3, optimized_output4, optimized_size4, download_file4 ] ) png_optimize.change( fn=optimize_image, inputs=[image_input, png_optimize, jpeg_quality, jpeg_resolution, webp_quality], outputs=[ optimized_output1, optimized_size1, download_file1, optimized_output2, optimized_size2, download_file2, optimized_output3, optimized_size3, download_file3, optimized_output4, optimized_size4, download_file4 ] ) jpeg_quality.change( fn=optimize_image, inputs=[image_input, png_optimize, jpeg_quality, jpeg_resolution, webp_quality], outputs=[ optimized_output1, optimized_size1, download_file1, optimized_output2, optimized_size2, download_file2, optimized_output3, optimized_size3, download_file3, optimized_output4, optimized_size4, download_file4 ] ) jpeg_resolution.change( fn=optimize_image, inputs=[image_input, png_optimize, jpeg_quality, jpeg_resolution, webp_quality], outputs=[ optimized_output1, optimized_size1, download_file1, optimized_output2, optimized_size2, download_file2, optimized_output3, optimized_size3, download_file3, optimized_output4, optimized_size4, download_file4 ] ) webp_quality.change( fn=optimize_image, inputs=[image_input, png_optimize, jpeg_quality, jpeg_resolution, webp_quality], outputs=[ optimized_output1, optimized_size1, download_file1, optimized_output2, optimized_size2, download_file2, optimized_output3, optimized_size3, download_file3, optimized_output4, optimized_size4, download_file4 ] ) download_button1.click(download_image, inputs=download_file1, outputs=download_file1) download_button2.click(download_image, inputs=download_file2, outputs=download_file2) download_button3.click(download_image, inputs=download_file3, outputs=download_file3) download_button4.click(download_image, inputs=download_file4, outputs=download_file4) demo.launch()