For learning purposes, I want to use the html input tag to select a jpeg image, retrieve the File Object, load it with fileReader and use the retrieved image string (base64) to create a new blob/file.
the service can upload the original file retrieved from the input just fine. However using my newFile the file get's corrupted and the file size somehow is larger.
I figure I'm doing something wrong with the blob constructor?
I'm using angular2 in typescript
<input type="file" (change)="onFileChanged($event)">
onFileChanged(event){
if (event.target.files && event.target.files[0]) {
let file = event.target.files[0];
let newFile;
let fr = new FileReader();
fr.onload = (event:any)=>{
let base64 = event.target.result
let img = base64.split(',')[1]
let blob = new Blob([window.atob(img)],{type:'image/jpeg'})
newFile = this.blobToFile(blob,'test')
}
fr.readAsDataURL(file)
console.log(file)
console.log(newFile)
this.service.upload(newFile).subscribe()
}
}
blobToFile(blob: Blob, fileName: string): File {
let b: any = blob;
b.lastModified = moment.now();
b.lastModifiedDate = new Date();
b.name = fileName;
b.webkitRelativePath="";
return <File>blob
}
EDIT------------ After finding out that fileReader is asynchronous, i've adjusted it a little bit and indeed the problem is with the blob constructor. loggin the both the target.result of original file and new one revealed that the base64 as been transmuted. Any ideas why?
if (event.target.files && event.target.files[0]) {
let file = event.target.files[0];
let base64: string = null;
if (/^image\//.test(file.type)) {
let reader = new FileReader();
reader.onload = (e: any) => {
console.log(e.target)
base64 = e.target.result
let img = base64.split(',')[1];
let blob = new Blob([img], { type: 'image/jpeg' })
console.log(blob);
let fr = new FileReader()
fr.onload = (event: any) => {
console.log(event.target)
}
fr.readAsDataURL(blob)
}
reader.readAsDataURL(file);
}
Modify your function like this. Because FileReader is asynchronous, to process the result, you need to do it inside the onload callback, but here, you are uploading the file outside of onload which at that point, is undefined or whatever initial value it contains.
onFileChanged(event){
if (event.target.files && event.target.files[0]) {
let file = event.target.files[0];
let newFile;
let fr = new FileReader();
fr.onload = (event:any)=>{
let base64 = event.target.result
let img = base64.split(',')[1]
let blob = new Blob([window.atob(img)],{type:'image/jpeg'})
newFile = this.blobToFile(blob,'test')
this.service.upload(newFile).subscribe()
}
fr.readAsDataURL(file)
console.log(file)
console.log(newFile) // Either prints undefined or whatever initial value it contains
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With