Oh no
Oh no

Reputation: 37

How to encode image to base64 in <q-uploader>?

I’m just starting to learn Quasar (and Vue). I’m trying to encode a picture into a Base64 and save to MongoDB. Undermentioned code works for the component but I can’t redo it for the component . I will be thankful for any help

<q-uploader v-model="image" @change="encodeToBase64" />
<q-btn type="btn" @click="sendPhoto">Save photo in mongo and go next page</q-btn>
methods: {
    encodeToBase64 (event) {
      event.preventDefault()
      const file = event.target.files[0]
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      const reader = new FileReader()
      reader.onload = event => {
        const img = new Image()
        img.onload = () => {
          if (img.width > MAX_WIDTH) {
            canvas.width = MAX_WIDTH
            canvas.height = (MAX_WIDTH * img.height) / img.width
          } else {
            canvas.width = img.width
            canvas.height = img.height
          }
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
          this.image = canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, '')
          console.log('RESULT/png', this.image)
        }
        img.src = event.target.result
        console.log('RESULT!', img.src)
      }
      reader.readAsDataURL(file)
    }
}
sendPhoto (event) {
      event.preventDefault()
      this.$store.dispatch('image/create', {account_id: this.account_selected, image: this.image})
        .then((res) => {
          this.$router.push({'path': '/nextReadings/' + res._id})
        })
        .catch((err) => {
          err.message = 'Error message'
          this.errorHandler(err.message)
        })
    }

Upvotes: 1

Views: 3109

Answers (1)

CodeFanatic
CodeFanatic

Reputation: 36

Here is how you can get a file in q-uploader into a base64 string. From there you should be able to figure out how to insert this string into your database.

1) Add a ref name to q-uploader. (I am using "files")

<q-uploader ref="files" label="My Label" :additional-fields="[{name: 'name', value: 'value'}]" multiple/>

2) You can now get the files in q-uploader anytime by using

this.$refs.files.files

3) Create the following two functions. This is the most concise and simple way that I have found to convert a javascript File into base64.

async encodeToBase64(files) {
  var attach = [];
  var reader = [];

  // loop through each of the files in q-uploader
  for (let i = 0; i < files.length; i++) {
      attach[i] = await this.singleFileToBase64(i, files, reader)
  }
  // returns an array of all the files in base64 format
  return attach;
},

singleFileToBase64(i, files, reader) {
    reader[i] = new FileReader();   
    // read the file into a base64 format 
    reader[i].readAsDataURL(files[i]);

    return new Promise((resolve, reject) => {
        reader[i].onerror = () => {
            reader[i].abort();
            reject("Insert error message here")
        };

        // return the base 64 string
        reader[i].onload = function () {
            resolve(reader[i].result);
        };
    })
},

Note: Using async, await and promises are key here. Otherwise reader.onload may not have run before you end up trying to use the output.

4) Call your function using the code from step 2

encodeToBase64(this.$refs.files.files)

Note: I have written this to reflect there being multiple files in q-uploader since that can be tricky to figure out with async, await and promises.

Note: I could probably get rid of the reader array and just declare it as a normal reader in singleFileToBase64 method... but I have not tested that.

Upvotes: 2

Related Questions