0

I'm currently creating a real-time chat application. This is a web application that uses node.js for the backend and uses socket.io to connect back and forth.

Currently, I'm working on creating user profiles with profile pictures. These profile pictures will be stored in a folder called images/profiles/. The file will be named by the user's id. For example: user with the id 1 will have their profile pictures stored in images/profiles/1.png. Very self-explanatory.

When the user submits the form to change their profile picture, the browser JavaScript will get the image, and send it to the server:

form.addEventListener('submit', handleForm)

function handleForm(event) {
  event.preventDefault(); // stop page from reloading

  let profilePicture; // set variable for profile picture
  let profilePictureInput = document.getElementById('profilePictureInput'); // get image input

  const files = profilePictureInput.files[0]; // get input's files

  if (files) {
    const fileReader = new FileReader(); // initialize file reader

    fileReader.readAsDataURL(files);
    fileReader.onload = function () {
      profilePicture = this.result; // put result into variable

      socket.emit("request-name", {
        profilePicture: profilePicture,
        id: userID,
      }); // send result, along with user id, to server
  }
}

I've commented most of the code so it's easy to follow. The server then gets this information. With this information, the server is supposed to convert the sent image to a png format (I can do whatever format, but it has to be the same format for all images). I am currently using the jimp library to do this task, but it doesn't seem to work.

const jimp = require('jimp'); // initialize Jimp

socket.on('request-name', (data) => { // when request has been received
  // read the buffer from image (I'm not 100% sure what Buffer.from() does, but I saw this online)
  jimp.read(Buffer.from(data.profilePicture), function (error, image) {
    if (error) throw error; // throw error if there is one

    image.write(`images/profiles/${data.id}.png`); // write image to designated place
  }
});

The error I get:

Error: Could not find MIME for Buffer <null>

I've scoured the internet for answers but was unable to find any. I am available to use another library if this helps. I can also change the file format (.png to .jpg or .jpeg, if needed; it just needs to be consistent with all files). The only things I cannot change are the use of JavaScript/Node.js and socket.io to send the information to the server.

Thank you in advance. Any and all help is appreciated.

IPSDSILVA
  • 1,667
  • 9
  • 27

1 Answers1

1

If you're just getting the data URI as a string, then you can construct a buffer with it and then use the built in fs to write the file. Make sure the relative path is accurate.

socket.on('request-name', data => {
  const imgBuffer = Buffer.from(data.profilePicture, 'base64');
  fs.writeFile(`images/profiles/${data.id}.png`, imgBuffer);
}
skara9
  • 4,042
  • 1
  • 6
  • 21
  • Hi, thanks for your response. I'm getting this error when I use this code: `TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined`. This is from the `fs.writeFile('filePath', imgBuffer);` line of code. – IPSDSILVA Jan 24 '22 at 01:46
  • @IPSDSILVA either use `writeFileSync` or pass in `()=>null` as the last parameter --- if you have a specific task to run after saving the file, you can do so within the callback – skara9 Jan 24 '22 at 02:10