Spaces:
Running
Running
Wkatir
commited on
Commit
·
422421f
1
Parent(s):
065cb1a
feat: adding a description and validation
Browse files- main.py +15 -8
- pages/4_Image_Converter.py +33 -8
main.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
import streamlit as st
|
2 |
|
|
|
3 |
def main():
|
4 |
st.set_page_config(
|
5 |
page_title="AI Design Hub",
|
@@ -10,34 +11,40 @@ def main():
|
|
10 |
st.title("AI Design Hub")
|
11 |
st.subheader("Automatización Inteligente de Diseño")
|
12 |
|
|
|
|
|
|
|
|
|
|
|
13 |
col1, col2, col3 = st.columns(3)
|
14 |
|
15 |
with col1:
|
16 |
st.markdown("### 🌟 Generador de Fondos AI")
|
17 |
st.markdown("""
|
18 |
-
- Expansión de imágenes con IA
|
19 |
-
- Mantenimiento de transparencia
|
20 |
- Descarga múltiple en ZIP
|
21 |
""")
|
22 |
|
23 |
with col2:
|
24 |
st.markdown("### ✂️ Smart Crop AI")
|
25 |
st.markdown("""
|
26 |
-
- Recorte inteligente con IA
|
27 |
-
- Detección de rostros
|
28 |
-
-
|
29 |
""")
|
30 |
|
31 |
with col3:
|
32 |
st.markdown("### 📁 Optimizador de Imágenes")
|
33 |
st.markdown("""
|
34 |
-
- Compresión inteligente
|
35 |
-
- Reducción de tamaño garantizada
|
36 |
- Procesamiento por lotes
|
37 |
""")
|
38 |
|
39 |
st.markdown("---")
|
40 |
st.markdown("Desarrollado por Wilmer Salazar")
|
41 |
|
|
|
42 |
if __name__ == "__main__":
|
43 |
-
main()
|
|
|
1 |
import streamlit as st
|
2 |
|
3 |
+
|
4 |
def main():
|
5 |
st.set_page_config(
|
6 |
page_title="AI Design Hub",
|
|
|
11 |
st.title("AI Design Hub")
|
12 |
st.subheader("Automatización Inteligente de Diseño")
|
13 |
|
14 |
+
st.markdown("""
|
15 |
+
**Herramientas para el flujo creativo:**
|
16 |
+
Nuestras soluciones aprovechan la API de Cloudinary para automatizar tareas y optimizar el rendimiento en procesos de diseño. Con estas herramientas, expande, recorta y optimiza imágenes de forma inteligente para potenciar tu creatividad.
|
17 |
+
""")
|
18 |
+
|
19 |
col1, col2, col3 = st.columns(3)
|
20 |
|
21 |
with col1:
|
22 |
st.markdown("### 🌟 Generador de Fondos AI")
|
23 |
st.markdown("""
|
24 |
+
- Expansión de imágenes con IA
|
25 |
+
- Mantenimiento de transparencia
|
26 |
- Descarga múltiple en ZIP
|
27 |
""")
|
28 |
|
29 |
with col2:
|
30 |
st.markdown("### ✂️ Smart Crop AI")
|
31 |
st.markdown("""
|
32 |
+
- Recorte inteligente con IA
|
33 |
+
- Detección de rostros
|
34 |
+
- Múltiples modos de recorte
|
35 |
""")
|
36 |
|
37 |
with col3:
|
38 |
st.markdown("### 📁 Optimizador de Imágenes")
|
39 |
st.markdown("""
|
40 |
+
- Compresión inteligente
|
41 |
+
- Reducción de tamaño garantizada
|
42 |
- Procesamiento por lotes
|
43 |
""")
|
44 |
|
45 |
st.markdown("---")
|
46 |
st.markdown("Desarrollado por Wilmer Salazar")
|
47 |
|
48 |
+
|
49 |
if __name__ == "__main__":
|
50 |
+
main()
|
pages/4_Image_Converter.py
CHANGED
@@ -12,7 +12,6 @@ st.set_page_config(
|
|
12 |
)
|
13 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
14 |
|
15 |
-
|
16 |
def convert_image(image_file, output_format):
|
17 |
"""
|
18 |
Verifica la integridad del archivo y lo convierte al formato de salida deseado.
|
@@ -22,17 +21,20 @@ def convert_image(image_file, output_format):
|
|
22 |
- output_format: cadena con el formato de salida deseado ('png' o 'jpg').
|
23 |
|
24 |
Retorna:
|
25 |
-
- Los bytes de la imagen convertida o None si
|
26 |
"""
|
27 |
image_name = getattr(image_file, 'name', 'Imagen sin nombre')
|
|
|
|
|
|
|
|
|
28 |
try:
|
29 |
# Intentamos abrir y verificar la integridad de la imagen
|
30 |
-
image_file.seek(0)
|
31 |
image = Image.open(image_file)
|
32 |
-
image.verify() #
|
33 |
logging.info(f"{image_name} verificado correctamente.")
|
34 |
|
35 |
-
#
|
36 |
image_file.seek(0)
|
37 |
image = Image.open(image_file)
|
38 |
except (UnidentifiedImageError, Exception) as e:
|
@@ -40,15 +42,38 @@ def convert_image(image_file, output_format):
|
|
40 |
logging.error(f"Error al verificar {image_name}: {e}")
|
41 |
return None
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
# Para JPG es necesario que la imagen esté en modo RGB
|
44 |
if output_format.lower() == "jpg" and image.mode != "RGB":
|
45 |
image = image.convert("RGB")
|
46 |
|
47 |
output_io = io.BytesIO()
|
48 |
try:
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
logging.info(f"{image_name} convertido a {output_format}.")
|
51 |
return output_io.getvalue()
|
|
|
52 |
except Exception as e:
|
53 |
st.error(f"Error al convertir {image_name}: {e}")
|
54 |
logging.error(f"Error al guardar {image_name}: {e}")
|
@@ -89,6 +114,7 @@ def main():
|
|
89 |
st.write(f"Procesando: {name}")
|
90 |
img_io = io.BytesIO(file_bytes)
|
91 |
output_bytes = convert_image(img_io, output_format)
|
|
|
92 |
if output_bytes:
|
93 |
converted_images.append((name, output_bytes))
|
94 |
|
@@ -103,7 +129,7 @@ def main():
|
|
103 |
zip_buffer = io.BytesIO()
|
104 |
with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
|
105 |
for name, img_bytes in converted_images:
|
106 |
-
#
|
107 |
base_name = name.rsplit('.', 1)[0]
|
108 |
zip_file.writestr(f"{base_name}.{output_format}", img_bytes)
|
109 |
|
@@ -114,6 +140,5 @@ def main():
|
|
114 |
mime="application/zip"
|
115 |
)
|
116 |
|
117 |
-
|
118 |
if __name__ == "__main__":
|
119 |
main()
|
|
|
12 |
)
|
13 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
14 |
|
|
|
15 |
def convert_image(image_file, output_format):
|
16 |
"""
|
17 |
Verifica la integridad del archivo y lo convierte al formato de salida deseado.
|
|
|
21 |
- output_format: cadena con el formato de salida deseado ('png' o 'jpg').
|
22 |
|
23 |
Retorna:
|
24 |
+
- Los bytes de la imagen convertida o None si no se puede/conviene convertir.
|
25 |
"""
|
26 |
image_name = getattr(image_file, 'name', 'Imagen sin nombre')
|
27 |
+
|
28 |
+
# Regresamos el puntero al inicio para asegurarnos de leer bien la imagen
|
29 |
+
image_file.seek(0)
|
30 |
+
|
31 |
try:
|
32 |
# Intentamos abrir y verificar la integridad de la imagen
|
|
|
33 |
image = Image.open(image_file)
|
34 |
+
image.verify() # Lanza excepción si el archivo está dañado
|
35 |
logging.info(f"{image_name} verificado correctamente.")
|
36 |
|
37 |
+
# Volvemos a posicionar el puntero y abrimos de nuevo para manipular
|
38 |
image_file.seek(0)
|
39 |
image = Image.open(image_file)
|
40 |
except (UnidentifiedImageError, Exception) as e:
|
|
|
42 |
logging.error(f"Error al verificar {image_name}: {e}")
|
43 |
return None
|
44 |
|
45 |
+
# Detectamos el formato real de la imagen usando PIL
|
46 |
+
# Nota: PIL suele identificar JPG como 'JPEG'
|
47 |
+
original_format = image.format.lower() if image.format else None
|
48 |
+
if original_format in ["jpeg", "jpg"]:
|
49 |
+
original_format = "jpg"
|
50 |
+
elif original_format == "png":
|
51 |
+
original_format = "png"
|
52 |
+
elif original_format == "webp":
|
53 |
+
original_format = "webp"
|
54 |
+
# Puedes agregar más formatos si lo deseas
|
55 |
+
|
56 |
+
# Si el formato original y el de salida son el mismo, advertimos y no convertimos
|
57 |
+
if original_format == output_format.lower():
|
58 |
+
st.warning(f"No se puede convertir '{image_name}' al mismo formato: '{output_format}'.")
|
59 |
+
return None
|
60 |
+
|
61 |
# Para JPG es necesario que la imagen esté en modo RGB
|
62 |
if output_format.lower() == "jpg" and image.mode != "RGB":
|
63 |
image = image.convert("RGB")
|
64 |
|
65 |
output_io = io.BytesIO()
|
66 |
try:
|
67 |
+
# Ajustamos la forma en que PIL reconoce los formatos
|
68 |
+
if output_format.lower() == "jpg":
|
69 |
+
pil_format = "JPEG"
|
70 |
+
else:
|
71 |
+
pil_format = output_format.upper()
|
72 |
+
|
73 |
+
image.save(output_io, format=pil_format)
|
74 |
logging.info(f"{image_name} convertido a {output_format}.")
|
75 |
return output_io.getvalue()
|
76 |
+
|
77 |
except Exception as e:
|
78 |
st.error(f"Error al convertir {image_name}: {e}")
|
79 |
logging.error(f"Error al guardar {image_name}: {e}")
|
|
|
114 |
st.write(f"Procesando: {name}")
|
115 |
img_io = io.BytesIO(file_bytes)
|
116 |
output_bytes = convert_image(img_io, output_format)
|
117 |
+
# Solo agregamos a 'converted_images' si hubo conversión exitosa
|
118 |
if output_bytes:
|
119 |
converted_images.append((name, output_bytes))
|
120 |
|
|
|
129 |
zip_buffer = io.BytesIO()
|
130 |
with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
|
131 |
for name, img_bytes in converted_images:
|
132 |
+
# Ajusta el nombre del archivo con la extensión deseada
|
133 |
base_name = name.rsplit('.', 1)[0]
|
134 |
zip_file.writestr(f"{base_name}.{output_format}", img_bytes)
|
135 |
|
|
|
140 |
mime="application/zip"
|
141 |
)
|
142 |
|
|
|
143 |
if __name__ == "__main__":
|
144 |
main()
|