데이터 URI를 파일로 변환한 후 FormData에 추가
Mozilla Hacks 사이트에 있는 것과 같은 HTML5 이미지 업로더를 다시 구현하려고 했지만 WebKit 브라우저와 함께 사용할 수 있습니다.작업의 일부는 이미지 파일을canvas
업로드할 FormData 객체에 추가합니다.
문제는...canvas
가지고 있다toDataURL
FormData 객체는 File API에서 File 또는 Blob 객체만 받아들입니다.
Mozilla 솔루션은 다음 Firefox 전용 함수를 사용하여canvas
:
var file = canvas.mozGetAsFile("foo.png");
...WebKit 브라우저에서는 사용할 수 없습니다.가장 좋은 해결책은 Data URI를 File 객체로 변환하는 것입니다. File API의 일부라고 생각했지만, 아무리 생각해도 그런 방법을 찾을 수 없습니다.
가능합니까?그렇지 않다면, 다른 대안이 있나요?
몇 가지 장난을 치고 나서, 나는 이것을 스스로 알아낼 수 있었다.
우선, 이것은 데이터를 변환합니다.블롭에 대한 URI:
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});
}
여기서 데이터를 파일로 업로드할 수 있도록 양식에 추가하는 것은 간단합니다.
var dataURL = canvas.toDataURL('image/jpeg', 0.5);
var blob = dataURItoBlob(dataURL);
var fd = new FormData(document.forms[0]);
fd.append("canvasImage", blob);
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'});
}
iOS와 Safari에서 동작합니다.
Stoive의 ArrayBuffer 솔루션을 사용해야 하지만 vava720에서 알 수 있듯이 BlobBuilder를 사용할 수 없습니다. 두 가지 모두 매시업입니다.
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' });
}
파이어폭스에는 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와 함께 사용하여 캔버스 또는 데이터 URL을 처리합니다.
예를 들어 다음과 같습니다.
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
non gecko 엔진브라우저용 메서드.
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()
파이어폭스 뿐만 아니라 모든 최신 브라우저에서 작동합니다.예를 들어 다음과 같습니다.
canvas.toBlob(
function(blob){
var fd = new FormData();
fd.append("myFile", blob, "thumb.jpg");
//continue do something...
},
'image/jpeg',
0.8
);
어쨌든 fetch ^^를 사용하여 base64를 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})
})
@Stoive와 @vava720 덕분에 이 두 가지를 조합하여 권장되지 않는 BlobBuilder와 ArrayBuffer를 사용하지 않게 되었습니다.
function dataURItoBlob(dataURI) {
'use strict'
var byteString,
mimestring
if(dataURI.split(',')[0].indexOf('base64') !== -1 ) {
byteString = atob(dataURI.split(',')[1])
} else {
byteString = decodeURI(dataURI.split(',')[1])
}
mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0]
var content = new Array();
for (var i = 0; i < byteString.length; i++) {
content[i] = byteString.charCodeAt(i)
}
return new Blob([new Uint8Array(content)], {type: mimestring});
}
진화하는 표준은 Mozilla가 추측할 위험이 있는 canvas.getAsFile()이 아니라 canvas.toBlob()인 것으로 보입니다.
지원되는 브라우저는 아직 없습니다.
이 멋진 실타래 고마워!
또한 승인된 답변을 시도하는 모든 사용자는 BlobBuilder에 주의해야 합니다. 지원이 제한(및 네임슬레이징)되어 있습니다.
var bb;
try {
bb = new BlobBuilder();
} catch(e) {
try {
bb = new WebKitBlobBuilder();
} catch(e) {
bb = new MozBlobBuilder();
}
}
BlobBuilder에 다른 라이브러리의 폴리필을 사용했습니까?
var BlobBuilder = (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder);
트라이 캐치 없이 사용할 수 있습니다.
체크_ca에 감사합니다.수고하셨습니다.
Stoive의 원래 답변은 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});
}
감사합니다! @steovi 。
ES6 버전에 지원을 추가하여 unescape에서 data로 변경하였습니다.URI(에스케이프 해제는 권장되지 않습니다.
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});
}
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);
심플화: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;
}
toDataURL은 문자열을 제공하며 이 문자열을 숨김 입력에 넣을 수 있습니다.
나도 라빈더 파얄과 똑같은 문제를 겪었고 답을 찾았어이것을 시험해 보세요.
var dataURL = canvas.toDataURL("image/jpeg");
var name = "image.jpg";
var parseFile = new Parse.File(name, {base64: dataURL.substring(23)});
언급URL : https://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata
'programing' 카테고리의 다른 글
MariaDB Galera 클러스터 설정 문제 (0) | 2022.12.11 |
---|---|
Python 변수의 유형을 확인하는 가장 좋은(자동) 방법은 무엇입니까? (0) | 2022.12.11 |
JSON에서 Guzle을 사용하여 POST 요청을 보내려면 어떻게 해야 하나요? (0) | 2022.12.11 |
포스트백 실행 실패: (2031) 준비된 문의 매개 변수에 대한 데이터가 제공되지 않았습니다. (0) | 2022.12.11 |
MVC는 JSF MVC 프레임워크에서 어떤 컴포넌트입니까? (0) | 2022.12.11 |