changeimage / app.py
Merlintxu's picture
Update app.py
5d4346b verified
raw
history blame
7.23 kB
import gradio as gr
from PIL import Image
import os
import tempfile
import pyheif
import ntpath
import shutil
def open_heic_image(image_path):
heif_file = pyheif.read(image_path)
img = Image.frombytes(
heif_file.mode,
heif_file.size,
heif_file.data,
"raw",
heif_file.mode,
heif_file.stride,
)
return img
def optimize_single_image(image_path, png_optimize, jpeg_quality, jpeg_resolution, webp_quality):
original_filename = ntpath.basename(image_path)
base_name, ext = os.path.splitext(original_filename)
if image_path.lower().endswith(".heic"):
img = open_heic_image(image_path)
else:
img = Image.open(image_path)
if img.mode not in ['RGB', 'L']:
img = img.convert('RGB')
original_size = os.path.getsize(image_path) / 1024 # tama帽o en KB
output_dir = tempfile.mkdtemp() # Crear un directorio temporal para las im谩genes optimizadas
optimized_images = []
if png_optimize:
lossless_output_path = os.path.join(output_dir, f"{base_name}-lossless.png")
img.save(lossless_output_path, format="PNG", optimize=True)
optimized_images.append(lossless_output_path)
lossy_output_path = os.path.join(output_dir, f"{base_name}-lossy.jpg")
img.save(lossy_output_path, format="JPEG", quality=jpeg_quality, optimize=True)
optimized_images.append(lossy_output_path)
reduced_output_path = os.path.join(output_dir, f"{base_name}-reduced_resolution.jpg")
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)
optimized_images.append(reduced_output_path)
webp_lossy_output_path = os.path.join(output_dir, f"{base_name}-lossy.webp")
img.save(webp_lossy_output_path, format="WEBP", quality=webp_quality, optimize=True)
optimized_images.append(webp_lossy_output_path)
return optimized_images
def optimize_zip_images(zip_file, png_optimize, jpeg_quality, jpeg_resolution, webp_quality):
with tempfile.TemporaryDirectory() as tmp_dir:
shutil.unpack_archive(zip_file.name, tmp_dir)
output_dir = tempfile.mkdtemp()
optimized_files = []
for root, _, files in os.walk(tmp_dir):
for file in files:
file_path = os.path.join(root, file)
optimized_images = optimize_single_image(file_path, png_optimize, jpeg_quality, jpeg_resolution, webp_quality)
for optimized_image in optimized_images:
output_path = os.path.join(output_dir, ntpath.basename(optimized_image))
shutil.move(optimized_image, output_path)
optimized_files.append(output_path)
zip_output_path = os.path.join(output_dir, "optimized_images.zip")
shutil.make_archive(zip_output_path.replace(".zip", ""), 'zip', output_dir)
return zip_output_path, optimized_files
with gr.Blocks() as demo:
gr.Markdown("""
# Optimizaci贸n de Im谩genes para la Web
Esta aplicaci贸n te permite optimizar im谩genes individuales o m煤ltiples im谩genes a trav茅s de un archivo ZIP.
- **Pesta帽a "Optimizaci贸n Tradicional"**: Sube una imagen individual para optimizaci贸n y descarga.
- **Pesta帽a "Optimizaci贸n por Lote"**: Elige los par谩metros de optimizaci贸n, sube un archivo ZIP con m煤ltiples im谩genes y descarga todas las im谩genes optimizadas.
""")
with gr.Tab("Optimizaci贸n Tradicional"):
image_input = gr.File(label="Sube tu imagen", file_types=['image', '.heic'])
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)
download_button1 = gr.File(label="Descargar", visible=True)
optimized_size1 = gr.Text(value="", interactive=False, show_label=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)
download_button2 = gr.File(label="Descargar", visible=True)
optimized_size2 = gr.Text(value="", interactive=False, show_label=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)
download_button3 = gr.File(label="Descargar", visible=True)
optimized_size3 = gr.Text(value="", interactive=False, show_label=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)
download_button4 = gr.File(label="Descargar", visible=True)
optimized_size4 = gr.Text(value="", interactive=False, show_label=False)
optimize_button.click(
fn=optimize_single_image,
inputs=[image_input, png_optimize, jpeg_quality, jpeg_resolution, webp_quality],
outputs=[
optimized_output1, optimized_size1, download_button1,
optimized_output2, optimized_size2, download_button2,
optimized_output3, optimized_size3, download_button3,
optimized_output4, optimized_size4, download_button4
]
)
with gr.Tab("Optimizaci贸n por Lote"):
with gr.Row():
png_optimize_batch = gr.Checkbox(label="Optimizar PNG", value=True)
jpeg_quality_batch = gr.Slider(label="Calidad JPEG", minimum=10, maximum=100, value=50, step=1)
jpeg_resolution_batch = gr.Slider(label="Resoluci贸n JPEG (%)", minimum=10, maximum=100, value=50, step=1)
webp_quality_batch = gr.Slider(label="Calidad WebP", minimum=10, maximum=100, value=50, step=1)
zip_input = gr.File(label="Sube tu archivo ZIP con im谩genes", file_types=['.zip'])
optimize_batch_button = gr.Button("Optimizar Im谩genes en ZIP")
batch_output_zip = gr.File(label="Descargar ZIP de im谩genes optimizadas", visible=True)
batch_gallery = gr.Gallery(label="Im谩genes optimizadas (individuales)").style(grid=[4])
def update_gallery(zip_file, png_optimize, jpeg_quality, jpeg_resolution, webp_quality):
zip_output_path, optimized_files = optimize_zip_images(zip_file, png_optimize, jpeg_quality, jpeg_resolution, webp_quality)
return zip_output_path, optimized_files
optimize_batch_button.click(
fn=update_gallery,
inputs=[zip_input, png_optimize_batch, jpeg_quality_batch, jpeg_resolution_batch, webp_quality_batch],
outputs=[batch_output_zip, batch_gallery]
)
demo.launch()