javascript - 객체 데이터 URI를 파일로 변환 한 다음 FormData에 추가합니다.



7 Answers

BlobBuilder와 ArrayBuffer는 이제 더 이상 사용되지 않습니다. 다음은 Blob 생성자로 업데이트 된 맨 위 주석의 코드입니다.

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'});
}
formdata 값 확인

Mozilla Hacks 사이트의 HTML5 이미지 업 로더를 다시 구현하려고 시도했지만 WebKit 브라우저에서 작동합니다. 작업의 일부는 canvas 개체에서 이미지 파일을 추출하여 업로드 할 수 있도록 FormData 개체에 추가하는 것입니다.

문제는 canvas 가 이미지 파일의 표현을 반환하는 toDataURL 함수를 가지고 있지만 FormData 객체는 File API 에서 File 또는 Blob 객체 만 허용한다는 것입니다.

Mozilla 솔루션은 canvas 에서 다음과 같은 Firefox 전용 기능을 canvas .

var file = canvas.mozGetAsFile("foo.png");

... WebKit 브라우저에서는 사용할 수 없습니다. 내가 생각할 수있는 최선의 해결책은 데이터 URI를 File 객체로 변환 할 수있는 방법을 찾는 것이다. File 객체는 File API의 일부분 일지 모르지만, 필자의 삶은 그럴 수 없다.

가능한가? 그렇지 않다면, 어떤 대안?

감사.




Firefox에는 canvas.toBlob()canvas.mozGetAsFile() 메소드가 있습니다.

하지만 다른 브라우저는 그렇지 않습니다.

캔버스에서 dataurl을 가져온 다음 dataurl을 blob 객체로 변환 할 수 있습니다.

다음은 dataURLtoBlob() 함수입니다. 매우 짧습니다.

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});
}

FormData에서이 함수를 사용하여 캔버스 또는 데이터를 처리합니다.

예 :

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

또한 비 게코 엔진 브라우저 용 HTMLCanvasElement.prototype.toBlob 메서드를 만들 수 있습니다.

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);
    };
}

이제 canvas.toBlob() 은 Firefox뿐만 아니라 모든 최신 브라우저에서 작동합니다. 예 :

canvas.toBlob(
    function(blob){
        var fd = new FormData();
        fd.append("myFile", blob, "thumb.jpg");
        //continue do something...
    },
    'image/jpeg',
    0.8
);



내가 선호하는 방식은 canvas.toBlob()

하지만 여하튼 여기서 base64를 fetch ^^를 사용하여 blob로 변환하는 또 다른 방법이 있습니다.

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})
})




var BlobBuilder = (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder);

try catch없이 사용할 수 있습니다.

check_ca에 감사합니다. 훌륭한 일.




share 은 ES6 버전입니다.

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});
  }
}

용법:

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);



감사! 이 솔루션에 대한 @steovi.

ES6 버전에 대한 지원을 추가하고 unescape에서 dataURI로 변경했습니다 (unescape는 사용되지 않습니다).

converterDataURItoBlob(dataURI) {
    let byteString;
    let mimeString;
    let ia;

    if (dataURI.split(',')[0].indexOf('base64') >= 0) {
      byteString = atob(dataURI.split(',')[1]);
    } else {
      byteString = encodeURI(dataURI.split(',')[1]);
    }
    // separate out the mime component
    mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ia], {type:mimeString});
}



나는 Ravinder Payal과 똑같은 문제가 있었는데 그 해답을 찾았습니다. 이 시도:

var dataURL = canvas.toDataURL("image/jpeg");

var name = "image.jpg";
var parseFile = new Parse.File(name, {base64: dataURL.substring(23)});



Related