es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Convertir caracteres de imagen extraños para usar en el atributo src de la imagen.

Obtengo una imagen mediante el comando GetObjectCommand en el backend (nodejs, express) y luego la paso al frontend (react).
Quiero mostrar la imagen con la etiqueta de img ¡¡¡pero los datos son extraños!!!

Lo puedo ver en postman:
enter image description here

Pero en la consola:
enter image description here

¿En qué formato debo convertirlo y cómo?
He intentado muchas soluciones (arraybuffer, FileReader, …) pero ninguna de ellas ha funcionado.
¿Hay algún problema con mi código de backend?

Backend:

const retrieveFile = asyncHandler(async (req, res) => {
  try {
    const param = {
      Bucket: 'mi-bucket',
      Key: req.params.id,
    };
    const data = await s3.send(new GetObjectCommand(param));

    data.Body.pipe(res); // ----------------------> imagen enviada al frontend
  } catch (err) {
    res.json('Error', err);
  }
});

Frontend:

const [imgFromStorage, setImgFromStorage] = useState('');

const getImageFromStorage = async () => {
  try {
    const { data } = await axios.get(
      '/api/storage/retrievefile/sadcat.jpg'
    );

    setImgFromStorage(data); // ------------------------> imagen recibida del backend
  } catch (err) {
    console.error(err);
  }
};
...
<img alt='myimg' src="{imgFromStorage}"> // ------------------> mostrar imagen
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema parece ser que los datos que se reciben del backend están en formato binario, lo cual no es directamente utilizable por la etiqueta img. Para mostrar la imagen, los datos binarios deben convertirse a un formato que pueda ser comprendido por los navegadores, como una URL de datos o una cadena codificada en base64.

    Una forma de lograr esta conversión es utilizando la API FileReader en el frontend. Aquí tienes un ejemplo:

    const getImageFromStorage = async () => {
      try {
        const response = await axios.get('/api/storage/retrievefile/sadcat.jpg', {
          responseType: 'arraybuffer', // establecer el tipo de respuesta como arraybuffer
        });
    
        const blob = new Blob([response.data], { type: 'image/jpeg' }); // crear un blob a partir del arraybuffer
        const reader = new FileReader();
    
        reader.onload = () => {
          setImgFromStorage(reader.result); // establecer el resultado del lector como la fuente de la imagen
        };
    
        reader.readAsDataURL(blob); // leer el blob como una URL de datos
      } catch (err) {
        console.error(err);
      }
    };
    

    Al establecer el responseType de la solicitud de axios en arraybuffer, nos aseguramos de que los datos de respuesta se devuelvan como datos binarios. Estos datos se convierten en un blob utilizando el constructor Blob, y se crea una instancia de FileReader para leer el blob como una URL de datos. El resultado del FileReader se establece como la fuente de la etiqueta img.

    Puede haber otras formas de lograr esta conversión, pero FileReader es un enfoque común para el manejo de datos binarios en el frontend.

    En cuanto al código del backend, la línea data.Body.pipe(res) parece ser correcta para enviar los datos de la imagen al frontend, por lo que el problema probablemente esté en el lado del frontend.

Comments are closed.