2014-11-06 6 views
12

내 이미지를 편집하는 데 glfx.js을 사용하고 있지만 toDataURL() 함수를 사용하여 해당 이미지 데이터를 가져 오려고 할 때 원본 이미지와 동일한 크기의 너비를 갖습니다. 영상).Canvas toDataURL()은 Firefox에서만 빈 이미지를 반환합니다.

이상한 점은 Chrome에서 스크립트가 완벽하게 작동한다는 것입니다.

내가 언급하고자하는 이미지가 onload 이벤트를 사용하여 canvas에로드되어 있습니다 :

  img.onload = function(){ 

       try { 
        canvas = fx.canvas(); 
       } catch (e) { 
        alert(e); 
        return; 
       } 

       // convert the image to a texture 
       texture = canvas.texture(img); 

       // draw and update canvas 
       canvas.draw(texture).update(); 

       // replace the image with the canvas 
       img.parentNode.insertBefore(canvas, img); 
       img.parentNode.removeChild(img); 

      } 

또한 내 이미지의 경로가 동일한 도메인에;

Firefox에서 문제는 저장 버튼을 눌렀을 때입니다. Chrome은 예상 결과를 반환하지만 Firefox는 다음을 반환합니다.

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA7YAAAIWCAYAAABjkRHCAAAHxklEQVR4nO3BMQEAAADCoPVPbQZ/oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
... [ lots of A s ] ... 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAzwD6aAABkwvPRgAAAABJRU5ErkJggg== 

이 결과가 발생할 수 있으며 어떻게 해결할 수 있습니까?

+0

편집중인 이미지가 같은 도메인에 있습니까? 명백한 것을 제외하기 만하면됩니다. – A1rPun

+0

예. 내가 언급 할 내 게시물을 편집합니다! 같은 도메인에 있지 않은 이미지가있는 Firefox (크롬이 아님)에 문제가 있습니까? – boyd

+0

비동기 작업이 어딘가에서 일어나는 것 같습니다. toDataURL()이 호출 될 때 이미지가로드되지 않으면 캔버스가 비어있게됩니다. – K3N

답변

11

캔버스에 그리는 시간과 toDataURL으로 전화하는 시간 사이에 비동기 이벤트가 발생할 가능성이 큽니다. 기본적으로 캔버스는 모든 컴포지션 후에 지워집니다. 하나는 렌더링하는 데 사용하는 어떤 이벤트 종료하기 전에

var gl = canvas.getContext("webgl", {preserveDrawingBuffer: true}); 

또는 확인 toDataURL을 호출 할 때와 같이 preserveDrawingBuffer: true와 WebGL이 컨텍스트를 작성하여 삭제되는 캔버스를 방지합니다. 예를 들어, 당신은이

function render() { 
    drawScene(); 
    requestAnimationFrame(render); 
} 
render(); 

을 그리고 다른 곳이

someElement.addEventListener('click', function() { 
    var data = someCanvas.toDataURL(); 
}, false); 

사람들이 이벤트를 수행 animation frame을하고 click가 동기화되지 않은 캔버스 그들을 호출 사이에 삭제 될 수 있습니다합니다. 참고 : 캔버스는 이중 버퍼 됨으로 지워지지는 않지만 버퍼에 영향을주는 버퍼 toDataURL 및 다른 명령은 지워집니다.

해결책은 preserveDrawingBuffer을 사용하거나 렌더링과 동일한 이벤트 내에서 toDataURL으로 전화하십시오. 예 :

var captureFrame = false; 

function render() { 
    drawScene(); 

    if (captureFrame) { 
    captureFrame = false; 
    var data = someCanvas.toDataURL(); 
    ... 
    } 

    requestAnimationFrame(render); 
} 
render(); 

someElement.addEventListener('click', function() { 
    captureFrame = true; 
}, false); 

preserveDrawingBuffer: false의 기본값은 무엇입니까? 특히 모바일에서 드로잉 버퍼를 보존 할 필요가 없으므로 훨씬 빨라질 수 있습니다. 그것을 보는 또 다른 방법은 브라우저에 2 개의 캔버스 사본이 필요하다는 것입니다. 그리는 사람과 그 사람이 표시하는 사람. 이 2 개의 버퍼를 처리하는 2 가지 방법이 있습니다. (A) 더블 버퍼. 그리기 명령을 내린 모든 이벤트를 빠져 나온 것으로 추측되는 렌더링이 끝나면 버퍼를 바꿔 놓고 다른 버퍼를 표시합니다. (B) 그리기 할 버퍼의 내용을 복사하여 표시된 버퍼에서 복사합니다 . 스와핑은 복사보다 훨씬 빠릅니다. 따라서 스와핑이 기본값입니다. 실제로 일어나는 것은 브라우저의 책임입니다. 유일한 요구 사항은 preserveDrawingBufferfalse 인 경우 합성 버퍼 (나중에 또 다른 비동기 이벤트이므로 예측할 수없는) 이후에 드로잉 버퍼가 지워지므로 preserveDrawingBuffertrue 인 경우 그리기 버퍼의 내용이 보존되도록 복사해야합니다.

+0

glfx.js 라이브러리를 사용하기 때문에 캔버스 및 렌더링 메서드에 직접 액세스 할 수 없습니다. 5 초의 시간 초과로 toDataURL 함수 이벤트를 호출했는데 작동하지 않았습니다. 나는 여기에 뭔가 비동기라고 생각하지 않는다 ... 다른 뭔가가 될 수 있을까? – boyd

+0

제한 시간이 5 초인 toDataURL을 호출하면 ASYNC 이벤트가 발생합니다. JavaScript를 사용하고 있습니다. glfx.js의 소스가 있습니다. 그것을 바꿔라. – gman

+0

나는 glfx 함수로 canvas 요소를 업데이트함으로써이 문제를 해결할 수있었습니다 ('update()'). 그러나이 문제가 왜 FF가 아닌 Chrome에서만 발생했는지 나는 알지 못합니다. 고맙습니다! – boyd