2014-11-06 169 views
12

我正在使用glfx.js編輯我的圖像,但是當我試圖使用toDataURL()函數獲取該圖像的數據時,我得到一個空白圖像(寬度與原始大小相同圖片)。Canvas toDataURL()僅在Firefox中返回空白圖像

奇怪的是,在Chrome中,腳本完美無缺。

我想提的是,圖像中canvas使用onload事件加載:

  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中)是當我點擊保存按鈕。鉻返回預期的結果,但火狐返回這個:

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

什麼可能導致這個結果,我該如何解決它?

+0

就是你正在編輯在同一個域的形象呢?只是爲了排除顯而易見的。 – A1rPun 2014-11-06 15:52:30

+0

是的。我會編輯我的帖子提及!在Firefox中(而不是在Chrome中)存在圖像不在同一域中的問題? – boyd 2014-11-06 15:53:30

+0

似乎是某個地方發生的異步操作。如果調用toDataURL()時未加載圖像,畫布將爲空白。 – K3N 2014-11-06 16:08:01

回答

11

最有可能在您畫到畫布的時間與您撥打toDataURL的時間之間存在一些異步事件。默認情況下,畫布在每個複合之後被清除。無論是防止被清除畫布通過創建具有preserveDrawingBuffer: true WebGL的上下文關係中

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

,或者確保toDataURL稱爲退出你使用渲染任何事件之前。例如,如果你這樣做

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

而且別的地方做

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

那些2項賽事,animation frameclick不同步和畫布可以調用它們之間被清除。注意:畫布不會被清除,因爲它是雙緩衝的,但緩衝區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)複製緩衝區的你繪製這樣做,就是BEING顯示的緩衝區的內容推斷。交換比複製要快得多。所以,交換是默認的。這取決於瀏覽器究竟發生了什麼。唯一的要求是,如果preserveDrawingBufferfalse是繪製緩衝區得到複合後清除(這又是一個異步事件,因此無法預測的),如果preserveDrawingBuffertrue那麼就必須複製,以便drawingbuffer的內容被保留。

+0

因爲我正在使用glfx.js庫,所以我沒有直接訪問畫布和渲染方法。我用5秒的超時時間調用了toDataURL函數事件,但它不起作用。我不認爲這裏是異步的...它可以是別的嗎? – boyd 2014-11-08 07:47:58

+0

以5秒的超時時間調用toDataURL是異步事件。你在JavaScript中。你有glfx.js的源代碼。更改。 – gman 2014-11-09 17:03:09

+0

我設法通過用glfx函數('update()')更新canvas元素來解決這個問題。但我不知道爲什麼這個問題只在FF而不在Chrome中。謝謝! – boyd 2014-11-10 14:13:05

相關問題