Merlintxu commited on
Commit
0902d61
1 Parent(s): 5c60085

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -43
app.py CHANGED
@@ -4,6 +4,7 @@ import os
4
  import tempfile
5
  import pyheif
6
  import ntpath
 
7
 
8
  def open_heic_image(image_path):
9
  heif_file = pyheif.read(image_path)
@@ -17,71 +18,74 @@ def open_heic_image(image_path):
17
  )
18
  return img
19
 
20
- def optimize_image(image, png_optimize, jpeg_quality, jpeg_resolution, webp_quality):
21
- # Obtener el nombre del archivo original sin la extensión
22
- original_filename = ntpath.basename(image.name)
23
  base_name, ext = os.path.splitext(original_filename)
24
 
25
- # Manejar archivos HEIC
26
- if image.name.lower().endswith(".heic"):
27
- img = open_heic_image(image.name)
28
  else:
29
- img = Image.open(image)
30
 
31
- # Convertir la imagen a RGB si está en RGBA o en un modo no soportado por JPEG
32
  if img.mode not in ['RGB', 'L']:
33
  img = img.convert('RGB')
34
 
35
- original_size = os.path.getsize(image.name) / 1024 # tamaño en KB
36
- output_dir = "/tmp/optimized_images"
37
- os.makedirs(output_dir, exist_ok=True)
38
 
39
- # Lista para almacenar los resultados
40
- results = []
41
 
42
- # Optimización para PNG
43
  if png_optimize:
44
  lossless_output_path = os.path.join(output_dir, f"{base_name}-lossless.png")
45
  img.save(lossless_output_path, format="PNG", optimize=True)
46
- lossless_size = os.path.getsize(lossless_output_path) / 1024
47
- percent_reduction = 100 * (original_size - lossless_size) / original_size
48
- results.append((Image.open(lossless_output_path), f"PNG: {lossless_size:.2f} KB (diferencia: {-percent_reduction:.2f} KB)", lossless_output_path))
49
 
50
- # Optimización para JPEG
51
  lossy_output_path = os.path.join(output_dir, f"{base_name}-lossy.jpg")
52
  img.save(lossy_output_path, format="JPEG", quality=jpeg_quality, optimize=True)
53
- lossy_size = os.path.getsize(lossy_output_path) / 1024
54
- percent_reduction = 100 * (original_size - lossy_size) / original_size
55
- results.append((Image.open(lossy_output_path), f"JPEG: {lossy_size:.2f} KB (diferencia: {-percent_reduction:.2f} KB)", lossy_output_path))
56
 
57
- # Reducción de resolución (JPEG)
58
  reduced_output_path = os.path.join(output_dir, f"{base_name}-reduced_resolution.jpg")
59
  new_resolution = (img.width * jpeg_resolution // 100, img.height * jpeg_resolution // 100)
60
  reduced_img = img.resize(new_resolution, Image.LANCZOS)
61
  reduced_img.save(reduced_output_path, format="JPEG", quality=jpeg_quality, optimize=True)
62
- reduced_size = os.path.getsize(reduced_output_path) / 1024
63
- percent_reduction = 100 * (original_size - reduced_size) / original_size
64
- results.append((Image.open(reduced_output_path), f"JPEG (resolución reducida): {reduced_size:.2f} KB (diferencia: {-percent_reduction:.2f} KB)", reduced_output_path))
65
 
66
- # Optimización para WebP
67
  webp_lossy_output_path = os.path.join(output_dir, f"{base_name}-lossy.webp")
68
  img.save(webp_lossy_output_path, format="WEBP", quality=webp_quality, optimize=True)
69
- webp_lossy_size = os.path.getsize(webp_lossy_output_path) / 1024
70
- percent_reduction = 100 * (original_size - webp_lossy_size) / original_size
71
- results.append((Image.open(webp_lossy_output_path), f"WebP: {webp_lossy_size:.2f} KB (diferencia: {-percent_reduction:.2f} KB)", webp_lossy_output_path))
72
 
73
- # Asegurarse de que todos los resultados están presentes (4 entradas)
74
- while len(results) < 4:
75
- results.append((None, "", None))
76
-
77
- # Dividir los resultados en imágenes, textos y rutas para descarga
78
- outputs = []
79
- for result in results:
80
- outputs.extend(result)
81
 
82
- return outputs
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
  with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
85
  with gr.Tab("Optimización Tradicional"):
86
  image_input = gr.File(label="Sube tu imagen", file_types=['image', '.heic'])
87
  optimize_button = gr.Button("Optimizar")
@@ -95,25 +99,24 @@ with gr.Blocks() as demo:
95
 
96
  with gr.Column():
97
  optimized_output2 = gr.Image(label="Optimización con pérdida (JPEG)")
98
- jpeg_quality = gr.Slider(label="Calidad JPEG", minimum=10, maximum=100, value=75, step=1)
99
  download_button2 = gr.File(label="Descargar", visible=True)
100
  optimized_size2 = gr.Text(value="", interactive=False, show_label=False)
101
 
102
  with gr.Column():
103
  optimized_output3 = gr.Image(label="Reducción de resolución (JPEG)")
104
- jpeg_resolution = gr.Slider(label="Resolución JPEG (%)", minimum=10, maximum=100, value=75, step=1)
105
  download_button3 = gr.File(label="Descargar", visible=True)
106
  optimized_size3 = gr.Text(value="", interactive=False, show_label=False)
107
 
108
  with gr.Column():
109
  optimized_output4 = gr.Image(label="Optimización WebP con pérdida")
110
- webp_quality = gr.Slider(label="Calidad WebP", minimum=10, maximum=100, value=75, step=1)
111
  download_button4 = gr.File(label="Descargar", visible=True)
112
  optimized_size4 = gr.Text(value="", interactive=False, show_label=False)
113
 
114
- # Conectar cada control a la función de optimización
115
  optimize_button.click(
116
- fn=optimize_image,
117
  inputs=[image_input, png_optimize, jpeg_quality, jpeg_resolution, webp_quality],
118
  outputs=[
119
  optimized_output1, optimized_size1, download_button1,
@@ -123,4 +126,23 @@ with gr.Blocks() as demo:
123
  ]
124
  )
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  demo.launch()
 
4
  import tempfile
5
  import pyheif
6
  import ntpath
7
+ import shutil
8
 
9
  def open_heic_image(image_path):
10
  heif_file = pyheif.read(image_path)
 
18
  )
19
  return img
20
 
21
+ def optimize_single_image(image_path, png_optimize, jpeg_quality, jpeg_resolution, webp_quality):
22
+ original_filename = ntpath.basename(image_path)
 
23
  base_name, ext = os.path.splitext(original_filename)
24
 
25
+ if image_path.lower().endswith(".heic"):
26
+ img = open_heic_image(image_path)
 
27
  else:
28
+ img = Image.open(image_path)
29
 
 
30
  if img.mode not in ['RGB', 'L']:
31
  img = img.convert('RGB')
32
 
33
+ original_size = os.path.getsize(image_path) / 1024 # tamaño en KB
34
+ output_dir = tempfile.mkdtemp() # Crear un directorio temporal para las imágenes optimizadas
 
35
 
36
+ optimized_images = []
 
37
 
 
38
  if png_optimize:
39
  lossless_output_path = os.path.join(output_dir, f"{base_name}-lossless.png")
40
  img.save(lossless_output_path, format="PNG", optimize=True)
41
+ optimized_images.append(lossless_output_path)
 
 
42
 
 
43
  lossy_output_path = os.path.join(output_dir, f"{base_name}-lossy.jpg")
44
  img.save(lossy_output_path, format="JPEG", quality=jpeg_quality, optimize=True)
45
+ optimized_images.append(lossy_output_path)
 
 
46
 
 
47
  reduced_output_path = os.path.join(output_dir, f"{base_name}-reduced_resolution.jpg")
48
  new_resolution = (img.width * jpeg_resolution // 100, img.height * jpeg_resolution // 100)
49
  reduced_img = img.resize(new_resolution, Image.LANCZOS)
50
  reduced_img.save(reduced_output_path, format="JPEG", quality=jpeg_quality, optimize=True)
51
+ optimized_images.append(reduced_output_path)
 
 
52
 
 
53
  webp_lossy_output_path = os.path.join(output_dir, f"{base_name}-lossy.webp")
54
  img.save(webp_lossy_output_path, format="WEBP", quality=webp_quality, optimize=True)
55
+ optimized_images.append(webp_lossy_output_path)
 
 
56
 
57
+ return optimized_images
58
+
59
+ def optimize_zip_images(zip_file, png_optimize, jpeg_quality, jpeg_resolution, webp_quality):
60
+ with tempfile.TemporaryDirectory() as tmp_dir:
61
+ shutil.unpack_archive(zip_file.name, tmp_dir)
62
+ output_dir = tempfile.mkdtemp()
63
+
64
+ optimized_files = []
65
 
66
+ for root, _, files in os.walk(tmp_dir):
67
+ for file in files:
68
+ file_path = os.path.join(root, file)
69
+ optimized_images = optimize_single_image(file_path, png_optimize, jpeg_quality, jpeg_resolution, webp_quality)
70
+ for optimized_image in optimized_images:
71
+ output_path = os.path.join(output_dir, ntpath.basename(optimized_image))
72
+ shutil.move(optimized_image, output_path)
73
+ optimized_files.append(output_path)
74
+
75
+ zip_output_path = os.path.join(output_dir, "optimized_images.zip")
76
+ shutil.make_archive(zip_output_path.replace(".zip", ""), 'zip', output_dir)
77
+
78
+ return zip_output_path, optimized_files
79
 
80
  with gr.Blocks() as demo:
81
+ gr.Markdown("""
82
+ # Optimización de Imágenes para la Web
83
+ Esta aplicación te permite optimizar imágenes individuales o múltiples imágenes a través de un archivo ZIP.
84
+
85
+ - **Pestaña "Optimización Tradicional"**: Sube una imagen individual para optimización y descarga.
86
+ - **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.
87
+ """)
88
+
89
  with gr.Tab("Optimización Tradicional"):
90
  image_input = gr.File(label="Sube tu imagen", file_types=['image', '.heic'])
91
  optimize_button = gr.Button("Optimizar")
 
99
 
100
  with gr.Column():
101
  optimized_output2 = gr.Image(label="Optimización con pérdida (JPEG)")
102
+ jpeg_quality = gr.Slider(label="Calidad JPEG", minimum=10, maximum=100, value=50, step=1)
103
  download_button2 = gr.File(label="Descargar", visible=True)
104
  optimized_size2 = gr.Text(value="", interactive=False, show_label=False)
105
 
106
  with gr.Column():
107
  optimized_output3 = gr.Image(label="Reducción de resolución (JPEG)")
108
+ jpeg_resolution = gr.Slider(label="Resolución JPEG (%)", minimum=10, maximum=100, value=50, step=1)
109
  download_button3 = gr.File(label="Descargar", visible=True)
110
  optimized_size3 = gr.Text(value="", interactive=False, show_label=False)
111
 
112
  with gr.Column():
113
  optimized_output4 = gr.Image(label="Optimización WebP con pérdida")
114
+ webp_quality = gr.Slider(label="Calidad WebP", minimum=10, maximum=100, value=50, step=1)
115
  download_button4 = gr.File(label="Descargar", visible=True)
116
  optimized_size4 = gr.Text(value="", interactive=False, show_label=False)
117
 
 
118
  optimize_button.click(
119
+ fn=optimize_single_image,
120
  inputs=[image_input, png_optimize, jpeg_quality, jpeg_resolution, webp_quality],
121
  outputs=[
122
  optimized_output1, optimized_size1, download_button1,
 
126
  ]
127
  )
128
 
129
+ with gr.Tab("Optimización por Lote"):
130
+ with gr.Row():
131
+ png_optimize_batch = gr.Checkbox(label="Optimizar PNG", value=True)
132
+ jpeg_quality_batch = gr.Slider(label="Calidad JPEG", minimum=10, maximum=100, value=50, step=1)
133
+ jpeg_resolution_batch = gr.Slider(label="Resolución JPEG (%)", minimum=10, maximum=100, value=50, step=1)
134
+ webp_quality_batch = gr.Slider(label="Calidad WebP", minimum=10, maximum=100, value=50, step=1)
135
+
136
+ zip_input = gr.File(label="Sube tu archivo ZIP con imágenes", file_types=['.zip'])
137
+ optimize_batch_button = gr.Button("Optimizar Imágenes en ZIP")
138
+
139
+ batch_output_zip = gr.File(label="Descargar ZIP de imágenes optimizadas", visible=True)
140
+ batch_output_files = gr.File(label="Descargar imágenes individuales", visible=True, multiple=True)
141
+
142
+ optimize_batch_button.click(
143
+ fn=optimize_zip_images,
144
+ inputs=[zip_input, png_optimize_batch, jpeg_quality_batch, jpeg_resolution_batch, webp_quality_batch],
145
+ outputs=[batch_output_zip, batch_output_files]
146
+ )
147
+
148
  demo.launch()