简体   繁体   中英

Converting base64 Image to file object in JavaScript

I am trying to create a file object from a base64 image which was cut from another image. I am able to do it but the resulting file size is almost thrice the actual size. Below is the function that I am using:

convertDataURItoFile(dataURI, fileName) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
    var byteString = atob(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

    // write the bytes of the string to an ArrayBuffer
    var ab = new ArrayBuffer(byteString.length);

    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    // write the ArrayBuffer to a blob, and you're done
    var blob: any = new Blob([ia], { type: mimeString });

    //A Blob() is almost a File() - it's just missing the two properties below which we will add
    blob.lastModifiedDate = new Date();
    blob.name = fileName;
    //Cast to a File() type
    return <File>blob;
  }

Any idea on why the file size increasing so drastically? How can I compress it? Thanks in advance.

I am trying to create a file object from a base64 image which was cut from another image. I am able to do it but the resulting file size is almost thrice the actual size.

Cannot reproduce resulting .size of Blob being thrice the size of the content of input data URI . Do you mean the data URI .length can be thrice the size of Blob .size ?

 function convertDataURItoFile(dataURI, fileName) { // convert base64 to raw binary data held in a string // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this var byteString = atob(dataURI.split(',')[1]); // separate out the mime component var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0] // write the bytes of the string to an ArrayBuffer var ab = new ArrayBuffer(byteString.length); var ia = new Uint8Array(ab); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } // write the ArrayBuffer to a blob, and you're done var blob = new Blob([ia], { type: mimeString }); //A Blob() is almost a File() - it's just missing the two properties below which we will add blob.lastModifiedDate = new Date(); blob.name = fileName; //Cast to a File() type console.log(`input data size: ${datauriLength} Blob.size: ${blob.size}`); return blob; } const [datauri, filename] = ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASoAAADCCAYAAAD+Wo90AAAABHNCSVQICAgIfAhkiAAAApVJREFUeJzt1DEBACAMwLCBf88ggZMeiYJeXTPnDEDY/=", "filename.png"]; const datauriLength = datauri.length; const reader = new FileReader; reader.onload = () => { console.log(`data URI: ${reader.result}`) document.querySelector("iframe").src = reader.result; }; reader.readAsDataURL(convertDataURItoFile(datauri, filename)); 
 <iframe></iframe> 

If .name and .lastModifiedDate need to be added to Blob , you can substitute using File constructor for Blob , which expects file name parameter to be set at second parameter to File constructor, and optionally expected .lastModidied and or .lastModifiedDate parameters at third parameter to constructor.

 function convertDataURItoFile(dataURI, fileName) { // convert base64 to raw binary data held in a string // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this var byteString = atob(dataURI.split(',')[1]); // separate out the mime component var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0] // write the bytes of the string to an ArrayBuffer var ab = new ArrayBuffer(byteString.length); var ia = new Uint8Array(ab); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } // write the ArrayBuffer to a blob, and you're done // use `File` constructor here var blob = new File([ia], fileName, { type: mimeString, lastModifiedDate: new Date() }); //A Blob() is almost a File() - it's just missing the two properties below which we will add // blob.lastModifiedDate = new Date(); // blob.name = fileName; //Cast to a File() type console.log(`input data size: ${datauriLength} Blob.size: ${blob.size}`); return blob; } const [datauri, filename] = ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASoAAADCCAYAAAD+Wo90AAAABHNCSVQICAgIfAhkiAAAApVJREFUeJzt1DEBACAMwLCBf88ggZMeiYJeXTPnDEDY/=", "filename.png"]; const datauriLength = datauri.length; const reader = new FileReader; reader.onload = () => { console.log(`data URI: ${reader.result}`) document.querySelector("iframe").src = reader.result; }; reader.readAsDataURL(convertDataURItoFile(datauri, filename)); 
 <iframe></iframe> 

You can also utilize fetch() to create and get Blob representation of data URI , see Answer by @Endless at Creating a Blob from a base64 string in JavaScript

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM