11

I've got a form for uploading Avatar image and I have to send the image file in the format of binary string; so far I've tried ReadAsBinaryString from FileReader but it's not working:( here's my code:

<form onSubmit={this.onFormSubmit}>
      <div className="row justify-content-center mb-2">
           <input type="file" id="avatar"  accept="image/png, image/jpeg" 
            onChange={this.uploadedImage} />
           <button type="submit" className="btn btn-sm btn-info">Send</button>
       </div>
  </form>

and that is how I'm trying to use ReadAsBinaryString in uploadedImage function:

uploadedImage(e) {
    let reader = new FileReader();
    let file = e.target.files[0];
    console.log(file); //I can see the file's info
    reader.onload= () => {
        var array = new Uint32Array(file);
        console.log("_+_array:",array); // the array is empty!
        var binaryString = String.fromCharCode.apply(null,array) ;
        console.log("__binaryString:",binaryString);
      this.setState({
        file: binaryString
      },()=>{
        console.log(this.state.file);//ergo file is set to an empty image
    });
    }
    reader.readAsArrayBuffer(file)
}

so to sum it up, I get a file but I can't convert it to byte array; Is there anything wrong with this code or this approach is completely wrong?

BlackSheep
  • 573
  • 2
  • 7
  • 19
  • What are you trying to do? Are you wanting to display the avatar image without uploading it to a server? – Dacre Denny May 06 '19 at 08:07
  • this is wrong `var array = new Uint32Array(file);` you are using `file` info variable to read the data, instead you **should use the `data` passed to handler** – Nikos M. May 06 '19 at 08:08
  • Possible duplicate of [How to go from Blob to ArrayBuffer](https://stackoverflow.com/questions/15341912/how-to-go-from-blob-to-arraybuffer) – Jorge Fuentes González May 06 '19 at 08:11
  • @DacreDenny I'm trying to get the image and then send it as a byte array to the server, U see the byte array is part of a data that I have to send to the backend API, I mean due to back-end restrictions, I have to convert the file to byte array and that is a must – BlackSheep May 06 '19 at 08:11

4 Answers4

23

This approach worked for me:

function readFileDataAsBase64(e) {
    const file = e.target.files[0];

    return new Promise((resolve, reject) => {
        const reader = new FileReader();

        reader.onload = (event) => {
            resolve(event.target.result);
        };

        reader.onerror = (err) => {
            reject(err);
        };

        reader.readAsDataURL(file);
    });
}

You can call reader.readAsBinaryString() if you wish to use binary string. More here: https://developer.mozilla.org/en-US/docs/Web/API/FileReader

tomericco
  • 1,544
  • 3
  • 19
  • 30
1

You are trying to read the file data using the file variable which contains the file info not the file contents. Try sth like the following:

FileReader documentation

uploadedImage(e) {
    let reader = new FileReader();
    let file = e.target.files[0];
    console.log(file); //I can see the file's info
    reader.onload= () => {
        var array = new Uint32Array(reader.result); // read the actual file contents
        console.log("_+_array:",array); // the array is empty!
        var binaryString = String.fromCharCode.apply(null,array) ;
        console.log("__binaryString:",binaryString);
      this.setState({
        file: binaryString
      },()=>{
        console.log(this.state.file);//ergo file is set to an empty image
    });
    }
    reader.readAsArrayBuffer(file)
}
Nikos M.
  • 8,033
  • 4
  • 36
  • 43
0

Just to add to tomericco's answer, here is one with few more lines to get the actual final byte array :

 const test_function = async () => {

      ... ... ...

      const get_file_array = (file) => {
          return new Promise((acc, err) => {
              const reader = new FileReader();
              reader.onload = (event) => { acc(event.target.result) };
              reader.onerror = (err)  => { err(err) };
              reader.readAsArrayBuffer(file);
          });
       }
       const temp = await get_file_array(files[0])
       console.log('here we finally ve the file as a ArrayBuffer : ',temp);
       const fileb = new Uint8Array(fileb)

       ... ... ...

  }

where file is directly the File object u want to read , this has to be done in a async function...

0
    const file = e.target.files[0];
    // we need to get the raw bytes
    const buffer = await file.arrayBuffer();
    // each entry of array should contain 8 bits
    const bytes = new Uint8Array(buffer);
Yilmaz
  • 35,338
  • 10
  • 157
  • 202