2014년 10월 13일 월요일

html5 canvas를 blob data로 변환하여 POST upload하는 방법

mobile web상에서 display하는 image를 업로드 하는 방법을 찾아봄.

일반적으로는 form data를 이용하여 선택된 image 파일을 업로드 하지만
form data 없이 load된 image나 Canvas를 업로드 하는 방법을 찾고자 하였음.

참고로 전송하려는 image(canvas내 image라도)가 다른 site에서 loading 된 것이라면
JavaScript의 동일 도메인 참조정책으로 인해 아래 방법을 사용할 수 없다.
 : http://stackoverflow.com/questions/2390232/why-does-canvas-todataurl-throw-a-security-exception
up vote51down voteaccepted
In the specs it says:
Whenever the toDataURL() method of a canvas element whose origin-clean flag is set to false is called, the method must raise a SECURITY_ERR exception.
If the image is coming from another server I don't think you can use toDataURL()
share|improve this answer
Same-Origin Policy(동일 도메인 정책)
http://charlie0301.blogspot.kr/2013/12/jquery-ajax-same-origin-policy-jsonp.html

-----------------------------------------------------------------

Canvas를 image/jpeg 형식의 blog data로 변환한 뒤 XMLHttpRequest를 사용하여 POST upload 하는 방법
http://stackoverflow.com/questions/18253378/javascript-blob-upload-with-formdata


function uploadCanvasData()
{
    var canvas = $('#ImageDisplay').get(0);
    var dataUrl = canvas.toDataURL("image/jpeg");
    var blob = dataURItoBlob(dataUrl);
    var formData = new FormData();
    formData.append("file", blob);

    var request = new XMLHttpRequest();
    request.onload = completeRequest;

    request.open("POST", "IdentifyFood");
    request.send(formData);
}

function dataURItoBlob(dataURI)
{
    var byteString = atob(dataURI.split(',')[1]);
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++)
    {
        ia[i] = byteString.charCodeAt(i);
    }

    var bb = new Blob([ab], { "type": mimeString });
    return bb;
}
answered Aug 15 '13 at 22:54
Max Ehrlich
639420




먼저 Canvas.toDataURL()을 통해서 DataURI를 뽑아낸다.

Syntax

canvas.toDataURL(type, encoderOptions);
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement.toDataURL

toDataURL() method는 사용자가 지정한 encoderOptions(default는 PNG)의 MIME을 가지는 96dpi resolution의 image dataURI를 제공한다.
(canvas의 height, width중 하나라도 0이면 "data:,"를 리턴한다고 함.)

제공되는 DataURI의 형식은 다음과 같다.

Syntax

The data URIs have the following syntax:
data:[<mediatype>][;base64],<data>
https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs

RFC 2397에 따라 해당 data를 document에 첨부할 수 있도록 위의 syntax로 표현하는 것이고 base64 encoding 방법이라던지 사용되는 protocol은 위키피디아를 참고하면 될듯

그래서 제공된 DataURI를 가지고 dataURItoBlob()함수를 사용하여 실제 data부분(<data>)을 뽑아내고 blob data로 변환한뒤 formdata에 삽입하여 POST uploading을 하게 된다.


Canvas.toDataURL() 사용예
http://m.mkexdev.net/106
http://www.html5canvastutorials.com/advanced/html5-canvas-get-image-data-url/

MDN에서 binary data를 보내는 방법에 대해서 설명한 포스팅
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data


dataURI를 blob으로 바꾸는 함수의 다른 버전이다.
: http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata

댓글 없음:

댓글 쓰기