I have a form which allows users to upload an image, crop that image (utilising vue-cropperjs wrapper component) then upload the cropped image (not the original image).
I'm unable to provide the correct format for the file in order to upload it. The file has been converted (encoded) the base64 image string to display it on the page. I now need to covert (decode) it back into a file format to upload it (as a default image upload form input would do).
The view component can be found at: https://www.npmjs.com/package/vue-cropperjs
And the following coded is based on the code from this package's example, i've just added a upload method for this example:
<template>
<div id="app">
<h2 style="margin: 0;">Vue CropperJS</h2>
<form @submit.prevent>
<input v-model="imageName" type="text" />
<hr />
<input
type="file"
name="image"
accept="image/*"
style="font-size: 1.2em; padding: 10px 0;"
@change="setImage"
/>
<br />
<div style="width: 400px; height:300px; border: 1px solid gray; display: inline-block;">
<vue-cropper
ref="cropper"
:guides="true"
:view-mode="2"
drag-mode="crop"
:auto-crop-area="0.5"
:min-container-width="250"
:min-container-height="180"
:background="true"
:src="imgSrc"
alt="Source Image"
:img-style="{ 'width': '400px', 'height': '300px' }"
></vue-cropper>
</div>
<img
:src="cropImg"
style="width: 200px; height: 150px; border: 1px solid gray"
alt="Cropped Image"
/>
<br />
<br />
<div>Debug Output: {{ cropImg }}</div>
<br />
<br />
<button @click="cropImage" v-if="imgSrc != ''" style="margin-right: 40px;">Crop</button>
<br />
<br />
<button @click="submitForm" v-if="imgSrc != ''">Submit Form</button>
</form>
</div>
</template>
<script>
import VueCropper from "vue-cropperjs";
import "cropperjs/dist/cropper.css";
export default {
components: {
VueCropper
},
data() {
return {
imageName: "",
imgSrc: "",
cropImg: "",
};
},
methods: {
setImage(e) {
const file = e.target.files[0];
if (!file.type.includes("image/")) {
alert("Please select an image file");
return;
}
if (typeof FileReader === "function") {
const reader = new FileReader();
reader.onload = event => {
this.imgSrc = event.target.result;
// rebuild cropperjs with the updated source
this.$refs.cropper.replace(event.target.result);
};
reader.readAsDataURL(file);
} else {
alert("Sorry, FileReader API not supported");
}
},
cropImage() {
// get image data for post processing, e.g. upload or setting image src
this.cropImg = this.$refs.cropper.getCroppedCanvas().toDataURL();
},
submitForm() {
console.log("imageName: " + this.imageName);
console.log("cropImg: " + this.cropImg); //Output: data:image/png;base64,iVBORw0KGgoAAA (please note: i've truncated the value for this example)
//example of an file upload to firebase storage (this could apply for different solutions)
//I need to convert the base64 date back into a file in order to upload.
let e = this.cropImg;
if(e != null) {
const file = e;
console.log("upload file: " + file.name);
fb.storage
.ref("images/" + file.name)
.put(file)
.then(response => {
//etc
}
}
}
}
};
</script>
I have done some research into blobs, decoding etc - but have been unable to find a solid solution.