File size: 5,528 Bytes
065cb1a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422421f
065cb1a
 
422421f
 
 
 
065cb1a
 
 
422421f
065cb1a
 
422421f
065cb1a
 
 
 
 
 
 
422421f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
065cb1a
 
 
 
 
 
422421f
 
 
 
 
 
 
065cb1a
 
422421f
065cb1a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422421f
065cb1a
 
 
 
 
 
 
 
 
 
 
 
 
 
422421f
065cb1a
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import streamlit as st
from PIL import Image, UnidentifiedImageError
import io
import zipfile
import logging

# Configuración inicial de la página y logging
st.set_page_config(
    page_title="Image Converter",
    page_icon="🖼️",
    layout="wide"
)
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")

def convert_image(image_file, output_format):
    """
    Verifica la integridad del archivo y lo convierte al formato de salida deseado.

    Parámetros:
    - image_file: objeto BytesIO del archivo de imagen.
    - output_format: cadena con el formato de salida deseado ('png' o 'jpg').

    Retorna:
    - Los bytes de la imagen convertida o None si no se puede/conviene convertir.
    """
    image_name = getattr(image_file, 'name', 'Imagen sin nombre')

    # Regresamos el puntero al inicio para asegurarnos de leer bien la imagen
    image_file.seek(0)

    try:
        # Intentamos abrir y verificar la integridad de la imagen
        image = Image.open(image_file)
        image.verify()  # Lanza excepción si el archivo está dañado
        logging.info(f"{image_name} verificado correctamente.")

        # Volvemos a posicionar el puntero y abrimos de nuevo para manipular
        image_file.seek(0)
        image = Image.open(image_file)
    except (UnidentifiedImageError, Exception) as e:
        st.error(f"El archivo {image_name} está dañado o es inválido: {e}")
        logging.error(f"Error al verificar {image_name}: {e}")
        return None

    # Detectamos el formato real de la imagen usando PIL
    # Nota: PIL suele identificar JPG como 'JPEG'
    original_format = image.format.lower() if image.format else None
    if original_format in ["jpeg", "jpg"]:
        original_format = "jpg"
    elif original_format == "png":
        original_format = "png"
    elif original_format == "webp":
        original_format = "webp"
    # Puedes agregar más formatos si lo deseas

    # Si el formato original y el de salida son el mismo, advertimos y no convertimos
    if original_format == output_format.lower():
        st.warning(f"No se puede convertir '{image_name}' al mismo formato: '{output_format}'.")
        return None

    # Para JPG es necesario que la imagen esté en modo RGB
    if output_format.lower() == "jpg" and image.mode != "RGB":
        image = image.convert("RGB")

    output_io = io.BytesIO()
    try:
        # Ajustamos la forma en que PIL reconoce los formatos
        if output_format.lower() == "jpg":
            pil_format = "JPEG"
        else:
            pil_format = output_format.upper()

        image.save(output_io, format=pil_format)
        logging.info(f"{image_name} convertido a {output_format}.")
        return output_io.getvalue()

    except Exception as e:
        st.error(f"Error al convertir {image_name}: {e}")
        logging.error(f"Error al guardar {image_name}: {e}")
        return None


def main():
    st.title("Conversor de Formatos de Imagen")
    st.markdown("Convierte tus imágenes al formato deseado y verifica la integridad de cada archivo.")

    # Selección del formato de salida
    output_format = st.selectbox(
        "Formato de salida",
        ["png", "jpg"],
        help="Selecciona el formato al que deseas convertir la imagen"
    )

    # Carga de imágenes
    uploaded_files = st.file_uploader(
        "Sube tus imágenes (Formatos soportados: PNG, JPG, JPEG, WEBP)",
        type=['png', 'jpg', 'jpeg', 'webp'],
        accept_multiple_files=True
    )

    if uploaded_files:
        st.header("Vista Previa Original")
        cols = st.columns(3)
        original_images = []
        for idx, file in enumerate(uploaded_files):
            file_bytes = file.getvalue()
            original_images.append((file.name, file_bytes))
            with cols[idx % 3]:
                st.image(file_bytes, caption=file.name, use_column_width=True)

        if st.button("✨ Convertir Imágenes"):
            converted_images = []
            for name, file_bytes in original_images:
                st.write(f"Procesando: {name}")
                img_io = io.BytesIO(file_bytes)
                output_bytes = convert_image(img_io, output_format)
                # Solo agregamos a 'converted_images' si hubo conversión exitosa
                if output_bytes:
                    converted_images.append((name, output_bytes))

            if converted_images:
                st.header("Imágenes Convertidas")
                cols = st.columns(3)
                for idx, (name, img_bytes) in enumerate(converted_images):
                    with cols[idx % 3]:
                        st.image(img_bytes, caption=f"{name} convertido a {output_format}", use_column_width=True)

                # Empaquetar las imágenes convertidas en un ZIP
                zip_buffer = io.BytesIO()
                with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
                    for name, img_bytes in converted_images:
                        # Ajusta el nombre del archivo con la extensión deseada
                        base_name = name.rsplit('.', 1)[0]
                        zip_file.writestr(f"{base_name}.{output_format}", img_bytes)

                st.download_button(
                    label="📥 Descargar todas las imágenes convertidas",
                    data=zip_buffer.getvalue(),
                    file_name="imagenes_convertidas.zip",
                    mime="application/zip"
                )

if __name__ == "__main__":
    main()