Convert Data URI to File then append to FormData

后端 未结 14 2627
逝去的感伤
逝去的感伤 2020-11-21 07:14

I\'ve been trying to re-implement an HTML5 image uploader like the one on the Mozilla Hacks site, but that works with WebKit browsers. Part of the task is to extract an imag

相关标签:
14条回答
  • 2020-11-21 07:28
    var BlobBuilder = (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder);
    

    can be used without the try catch.

    Thankx to check_ca. Great work.

    0 讨论(0)
  • 2020-11-21 07:31

    After playing around with a few things, I managed to figure this out myself.

    First of all, this will convert a dataURI to a Blob:

    function dataURItoBlob(dataURI) {
        // convert base64/URLEncoded data component to raw binary data held in a string
        var byteString;
        if (dataURI.split(',')[0].indexOf('base64') >= 0)
            byteString = atob(dataURI.split(',')[1]);
        else
            byteString = unescape(dataURI.split(',')[1]);
    
        // separate out the mime component
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    
        // write the bytes of the string to a typed array
        var ia = new Uint8Array(byteString.length);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
    
        return new Blob([ia], {type:mimeString});
    }
    

    From there, appending the data to a form such that it will be uploaded as a file is easy:

    var dataURL = canvas.toDataURL('image/jpeg', 0.5);
    var blob = dataURItoBlob(dataURL);
    var fd = new FormData(document.forms[0]);
    fd.append("canvasImage", blob);
    
    0 讨论(0)
  • 2020-11-21 07:31

    This one works in iOS and Safari.

    You need to use Stoive's ArrayBuffer solution but you can't use BlobBuilder, as vava720 indicates, so here's the mashup of both.

    function dataURItoBlob(dataURI) {
        var byteString = atob(dataURI.split(',')[1]);
        var ab = new ArrayBuffer(byteString.length);
        var ia = new Uint8Array(ab);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        return new Blob([ab], { type: 'image/jpeg' });
    }
    
    0 讨论(0)
  • 2020-11-21 07:35

    The original answer by Stoive is easily fixable by changing the last line to accommodate Blob:

    function dataURItoBlob (dataURI) {
        // convert base64 to raw binary data held in a string
        // doesn't handle URLEncoded DataURIs
        var byteString;
        if (dataURI.split(',')[0].indexOf('base64') >= 0)
            byteString = atob(dataURI.split(',')[1]);
        else
            byteString = unescape(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
        return new Blob([ab],{type: mimeString});
    }
    
    0 讨论(0)
  • 2020-11-21 07:38

    My preferred way is canvas.toBlob()

    But anyhow here is yet another way to convert base64 to a blob using fetch ^^,

    var url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
    
    fetch(url)
    .then(res => res.blob())
    .then(blob => {
      var fd = new FormData()
      fd.append('image', blob, 'filename')
      
      console.log(blob)
    
      // Upload
      // fetch('upload', {method: 'POST', body: fd})
    })

    0 讨论(0)
  • 2020-11-21 07:40

    BlobBuilder and ArrayBuffer are now deprecated, here is the top comment's code updated with Blob constructor:

    function dataURItoBlob(dataURI) {
        var binary = atob(dataURI.split(',')[1]);
        var array = [];
        for(var i = 0; i < binary.length; i++) {
            array.push(binary.charCodeAt(i));
        }
        return new Blob([new Uint8Array(array)], {type: 'image/jpeg'});
    }
    
    0 讨论(0)
提交回复
热议问题