레이블이 image인 게시물을 표시합니다. 모든 게시물 표시
레이블이 image인 게시물을 표시합니다. 모든 게시물 표시

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

2014년 5월 14일 수요일

Tizen native app 개발 시 nine patched png 처리 이슈

아래 내용은 Tizen 2.2 기반이라 상위 버전에서는 별 의미 없는 내용입니다.
--------------------------------------------------------------------------- nine patch 적용된 png 파일을 사용하다보니
bitmap을 읽어오는 API에 따라서 nine patch image로 인식이 되지 않을 수 있어서 정리함.
(내가 방법을 모를지도..)

아래는 tizen 내부 저장소에서 그림을 읽어오는 sample code

result
MainForm::OnDraw(void)
{

// App resource(res/screen-density-xhigh)에서 나인패치 이미지 가져오는 예
// 하지만 이렇게 가져온 bitmap은 nine patch 로 인식 안됨 .
// false == pBitmap->IsNinePatchedBitmap()
// canvas->DrawNinePatchedBitmap() 시 에러메세지 발생

Bitmap* pBitmap = pAppResource->GetBitmapN(L"ninepatch.9.png");

// 아래는 App 영역내 data 폴더에 저장된 나인패치 이미지를 가져오는 예
// 이때는 정상적으로 인식됨.

Image image;
Bitmap* pBitmap = null;

image.Construct();
String filePath = App::GetInstance()->GetAppRootPath() + L"data/ninepatch.9.png";
pBitmap = image.DecodeN(filePath, BITMAP_PIXEL_FORMAT_ARGB8888, 100, 100);


Canvas* canvas = this->GetCanvasN(rect);
if (canvas != null)
{

r = canvas->DrawNinePatchedBitmap(Rectangle(0,0,100,100), *pBitmap);
AppLog("%d", r);

delete canvas;
}

Form::OnDraw();
}