Convert Data URI to File then append to FormData

后端 未结 14 2622
逝去的感伤
逝去的感伤 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:17

    The evolving standard looks to be canvas.toBlob() not canvas.getAsFile() as Mozilla hazarded to guess.

    I don't see any browser yet supporting it :(

    Thanks for this great thread!

    Also, anyone trying the accepted answer should be careful with BlobBuilder as I'm finding support to be limited (and namespaced):

        var bb;
        try {
            bb = new BlobBuilder();
        } catch(e) {
            try {
                bb = new WebKitBlobBuilder();
            } catch(e) {
                bb = new MozBlobBuilder();
            }
        }
    

    Were you using another library's polyfill for BlobBuilder?

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

    I had exactly the same problem as Ravinder Payal, and I've found the answer. Try this:

    var dataURL = canvas.toDataURL("image/jpeg");
    
    var name = "image.jpg";
    var parseFile = new Parse.File(name, {base64: dataURL.substring(23)});
    
    0 讨论(0)
  • 2020-11-21 07:19

    Here is an ES6 version of Stoive's answer:

    export class ImageDataConverter {
      constructor(dataURI) {
        this.dataURI = dataURI;
      }
    
      getByteString() {
        let byteString;
        if (this.dataURI.split(',')[0].indexOf('base64') >= 0) {
          byteString = atob(this.dataURI.split(',')[1]);
        } else {
          byteString = decodeURI(this.dataURI.split(',')[1]);
        }
        return byteString;
      }
    
      getMimeString() {
        return this.dataURI.split(',')[0].split(':')[1].split(';')[0];
      }
    
      convertToTypedArray() {
        let byteString = this.getByteString();
        let ia = new Uint8Array(byteString.length);
        for (let i = 0; i < byteString.length; i++) {
          ia[i] = byteString.charCodeAt(i);
        }
        return ia;
      }
    
      dataURItoBlob() {
        let mimeString = this.getMimeString();
        let intArray = this.convertToTypedArray();
        return new Blob([intArray], {type: mimeString});
      }
    }
    

    Usage:

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

    toDataURL gives you a string and you can put that string to a hidden input.

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

    make it simple :D

    function dataURItoBlob(dataURI,mime) {
        // convert base64 to raw binary data held in a string
        // doesn't handle URLEncoded DataURIs
    
        var byteString = window.atob(dataURI);
    
        // separate out the mime component
    
    
        // write the bytes of the string to an ArrayBuffer
        //var ab = new ArrayBuffer(byteString.length);
        var ia = new Uint8Array(byteString.length);
        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: mime });
    
        return blob;
    }
    
    0 讨论(0)
  • 2020-11-21 07:26

    Firefox has canvas.toBlob() and canvas.mozGetAsFile() methods.

    But other browsers do not.

    We can get dataurl from canvas and then convert dataurl to blob object.

    Here is my dataURLtoBlob() function. It's very short.

    function dataURLtoBlob(dataurl) {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while(n--){
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], {type:mime});
    }
    

    Use this function with FormData to handle your canvas or dataurl.

    For example:

    var dataurl = canvas.toDataURL('image/jpeg',0.8);
    var blob = dataURLtoBlob(dataurl);
    var fd = new FormData();
    fd.append("myFile", blob, "thumb.jpg");
    

    Also, you can create a HTMLCanvasElement.prototype.toBlob method for non gecko engine browser.

    if(!HTMLCanvasElement.prototype.toBlob){
        HTMLCanvasElement.prototype.toBlob = function(callback, type, encoderOptions){
            var dataurl = this.toDataURL(type, encoderOptions);
            var bstr = atob(dataurl.split(',')[1]), n = bstr.length, u8arr = new Uint8Array(n);
            while(n--){
                u8arr[n] = bstr.charCodeAt(n);
            }
            var blob = new Blob([u8arr], {type: type});
            callback.call(this, blob);
        };
    }
    

    Now canvas.toBlob() works for all modern browsers not only Firefox. For example:

    canvas.toBlob(
        function(blob){
            var fd = new FormData();
            fd.append("myFile", blob, "thumb.jpg");
            //continue do something...
        },
        'image/jpeg',
        0.8
    );
    
    0 讨论(0)
提交回复
热议问题