HTML5 캔버스를 업로드할 파일로 변환하시겠습니까?
표준 HTML 파일 업로드는 다음과 같이 작동합니다.
<g:form method="post" accept-charset="utf-8" enctype="multipart/form-data"
name="form" url="someurl">
<input type="file" name="file" id="file" />
</form>
저의 경우 html5 캔버스에 이미지를 로드하여 서버에 파일로 제출하고자 합니다.할 수 있습니다.
var canvas; // some canvas with an image
var url = canvas.toDataURL();
이미지/png를 base64로 표시합니다.
Base64 이미지를 입력타입 파일과 동일하게 서버로 전송하려면 어떻게 해야 합니까?
문제는 base64 파일이 입력 유형="file" 안에 있는 파일과 같은 유형이 아니라는 것입니다.
서버에 대해 타입이 동일한 base64를 어떻게든 변환할 수 있습니까?
보안상의 이유로 파일 입력 요소의 값을 직접 설정할 수 없습니다.
파일 입력 요소를 사용하려는 경우:
- 캔버스에서 이미지를 만듭니다(완료한 대로).
- 해당 이미지를 새 페이지에 표시합니다.
- 사용자가 로컬 드라이브에 마우스 오른쪽 단추로 클릭하여 저장하도록 합니다.
- 그러면 파일 입력 요소를 사용하여 새로 생성된 파일을 업로드할 수 있습니다.
또는 Ajax를 사용하여 캔버스 데이터를 게시할 수 있습니다.
블롭에 대해서 물어봤잖아요
var blobBin = atob(dataURL.split(',')[1]);
var array = [];
for(var i = 0; i < blobBin.length; i++) {
array.push(blobBin.charCodeAt(i));
}
var file=new Blob([new Uint8Array(array)], {type: 'image/png'});
var formdata = new FormData();
formdata.append("myNewFileName", file);
$.ajax({
url: "uploadFile.php",
type: "POST",
data: formdata,
processData: false,
contentType: false,
}).done(function(respond){
alert(respond);
});
참고: blob은 일반적으로 최신 브라우저에서 지원됩니다.
캔버스 이미지를 베이스64로 변환한 다음 베이스64에서 바이너리로 변환해야 합니다.이 작업은 를 사용하여 수행됩니다..toDataURL()
그리고.dataURItoBlob()
여러 SO 답변, 다양한 블로그 게시물 및 튜토리얼을 종합해야 하는 매우 어리석은 과정이었습니다.
Ateik의 의견에 응답하여 원본 링크를 보는 데 문제가 있을 경우 원본 게시물을 복제하는 fiddle을 제공합니다.여기서 제 프로젝트를 진행할 수도 있습니다.
많은 코드가 있지만 제가 하는 일의 핵심은 캔버스 요소를 사용하는 것입니다.
<canvas id="flatten" width="800" height="600"></canvas>
상황을 2D로 설정
var snap = document.getElementById('flatten');
var flatten = snap.getContext('2d');
캔버스 => 베이스64 => 바이너리
function postCanvasToURL() {
// Convert canvas image to Base64
var img = snap.toDataURL();
// Convert Base64 image to binary
var file = dataURItoBlob(img);
}
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});
}
필요한 것이 그것뿐이라면 base64에서 멈출 수 있습니다. 제 경우에는 db를 사용하지 않고 twitter(OAuth 사용)에 데이터를 전달할 수 있도록 다시 binary로 변환해야 했습니다.당신은 꽤 멋진 바이너리를 트윗할 수 있고, 트위터는 그것을 다시 이미지로 변환할 것입니다.
이것이 결국 저에게 효과가 있었던 것입니다.
canvas.toBlob((blob) => {
let file = new File([blob], "fileName.jpg", { type: "image/jpeg" })
}, 'image/jpeg');
현재 사양(17년 4월 현재 지원이 거의 없음)
Canvas.toBlob();
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
편집:
링크는 @pixelomo 응답과 거의 동일하지만 네이티브와 동일한 api를 사용하는 폴리필(문법에서 더 느린 것처럼 보이는)을 제공합니다.toBlob
방법:
DataURL에 기반한 저성능 폴리필:
if (!HTMLCanvasElement.prototype.toBlob) {
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
value: function (callback, type, quality) {
var canvas = this;
setTimeout(function() {
var binStr = atob( canvas.toDataURL(type, quality).split(',')[1] ),
len = binStr.length,
arr = new Uint8Array(len);
for (var i = 0; i < len; i++ ) {
arr[i] = binStr.charCodeAt(i);
}
callback( new Blob( [arr], {type: type || 'image/png'} ) );
});
}
});
}
이 방법으로 사용하려면:
canvas.toBlob(function(blob){...}, 'image/jpeg', 0.95); // JPEG at 95% quality
아니면
canvas.toBlob(function(blob){...}); // PNG
또 다른 해결책은 숨겨진 필드에 있는 varurl로 데이터를 보내고 해독하여 서버에 저장하는 것입니다.
Python Django의 예:
if form.is_valid():
url = form.cleaned_data['url']
url_decoded = b64decode(url.encode())
content = ContentFile(url_decoded)
your_model.model_field.save('image.png', content)
const canvas = document.querySelector("canvas");
canvas.toBlob(blob => {
const file = new File([blob], "image.png");
});
전에는 아주 간단하게 했었습니다.
var formData = new FormData(),
uploadedImageName = 'selfie.png';
canvas.toBlob(function (blob) {
formData.append('user_picture', blob, uploadedImageName);
$.ajax({
data: formData,
type: "POST",
dataType: "JSON",
url: '',
processData: false,
contentType: false,
});
});
2023년 답변을 사용합니다.toBlob
TypeScript:
const dataBlob = await new Promise<Blob | null>(
(resolve) => canvas.toBlob(
(blob) => resolve(blob),
"image/png",
)
);
언급URL : https://stackoverflow.com/questions/19032406/convert-html5-canvas-into-file-to-be-uploaded
'programing' 카테고리의 다른 글
ajax success에서 부트스트랩 모드를 여는 방법 (0) | 2023.09.27 |
---|---|
AJAX & Web Api Post Method - 어떻게 작동합니까? (0) | 2023.09.27 |
여러 선택 항목에 가입 (0) | 2023.09.27 |
node.js는 JS 대신 커피스크립트를 사용할 수 있습니까? (0) | 2023.09.27 |
집중적인 내용 편집 사전 영역의 테두리를 제거하려면 어떻게 해야 합니까? (0) | 2023.09.27 |