2012-01-26 65 views
1

我正在處理每個視頻幀並將結果繪製到畫布上,以便操縱HTML5視頻。下面的例子簡單地忽略了所有RGB分量具有值< 32的任何源像素;HTML5 canvas.getImageData()拋出SECURITY_ERR:在移動設備上調用drawImage()後,DOM異常18對於視頻幀

它似乎在我的桌面瀏覽器(chrome)中正常工作,但當我嘗試使用支持HTML5的移動瀏覽器(iPad或Playbook)查看頁面時,bc.getImageData()會拋出DOM異常18. 但是,如果我刪除將視頻幀繪製到後畫布的代碼行(即第37行--bc.drawImage(v,0,0,w,h);),則不會再引發異常。

我懷疑由於某種原因,只要我調用drawImage()並傳入視頻,canvas的origin-clear標誌就設置爲false。這可能嗎?

託管的例子可以在這裏找到:http://petermares.com/samples/tvtest/

任何反饋,將不勝感激。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html> 
<title>Transparent Video Test</title> 
<script> 
document.addEventListener('DOMContentLoaded', function() 
{ 
    var v = document.getElementById('v'); 
    var canvas = document.getElementById('c'); 
    var context = canvas.getContext('2d'); 
    var back = document.createElement('canvas'); 
    var backcontext = back.getContext('2d'); 
    var img = new Image(); 
    img.src = "./background.jpg"; 

    var cw,ch; 

    v.addEventListener('play', function() 
    { 
     v.style.visibility = 'hidden'; 
     cw = v.clientWidth; 
     ch = v.clientHeight; 
     canvas.width = cw; 
     canvas.height = ch; 
     back.width = cw; 
     back.height = ch; 
     draw(v,context,backcontext,cw,ch,img); 
    },false); 

},false); 

function draw(v,c,bc,w,h,img) 
{ 
    if(v.paused || v.ended) return false; 

    // First, draw it into the backing canvas 
    bc.drawImage(v,0,0,w,h); 
    c.fillStyle = "white"; 
    c.fillRect(0, 0, w, h); 
    c.drawImage(img, 0, h/2-img.height/2); 

    try 
    { 
     // Grab the pixel data from the backing canvas 
     try 
     { 
      var idata = bc.getImageData(0,0,w,h); 
     } 
     catch (e) 
     { 
      alert("bc.getImageData(): " + e); 
      return; 
     } 
     var data = idata.data; 

     // grab the pixel data from the target canvas 
     try 
     { 
      var tdata = c.getImageData(0, 0, w, h); 
     } 
     catch (e) 
     { 
      alert("c.getImageData(): " + e); 
      return; 
     } 
     var rdata = tdata.data; 
     // Loop through the pixels, turning them grayscale 
     for(var i = 0; i < data.length; i+=4) 
     { 
      // source pixel 
      var rs = data[i]; 
      var gs = data[i+1]; 
      var bs = data[i+2]; 
      var as = data[i+3]; 
      // target pixel 
      var rt = rdata[i]; 
      var gt = rdata[i+1]; 
      var bt = rdata[i+2]; 
      var at = rdata[i+3]; 

      if (rs < 32 && gs < 32 && bs < 32) 
      { 
       rs = rt; 
       gs = gt; 
       bs = bt; 
      } 

      data[i] = rs; 
      data[i+1] = gs; 
      data[i+2] = bs; 
      data[i+3] = as; 
     } 
     idata.data = data; 
     // Draw the pixels onto the visible canvas 
     try 
     { 
      c.putImageData(idata,0,0); 
     } 
     catch (e) 
     { 
      alert("c.putImageData(): " + e); 
      return; 
     } 
    } 
    catch (e) 
    { 
     alert("Main loop" + e); 
     return; 
    } 

    // Start over! 
    setTimeout(draw,20,v,c,bc,w,h, img); 
    } 
    </script> 

    <body> 
    <video id="v" autoplay loop="loop" webkit-playsinline> 
     <source src="video/compressed.ogv" type="video/ogg" /> 
     <source src="video/compressed.mp4" type="video/mp4" /> 
    </video> 
    <canvas id="c"> 
    </canvas> 

    <style> 
    #c { 
    position: absolute; 
    top: 0%; 
    left: 0%; 
    } 

    #v { 
    position: absolute; 
    top: 50%; 
    left: 50%; 
    margin: -180px 0 0 -500px; 
    } 
    </style> 
    </body> 
</html> 

回答

0

是的。您的瀏覽器認爲<canvas>受到外部源圖像的污染。這並不一定是這種情況(真的),但瀏覽器可能不支持它/是越野車。

如果它在Chrome中有效,那麼不幸的是它絕對是一個瀏覽器問題。

https://developer.mozilla.org/en/CORS_Enabled_Image

由於問題的瀏覽器是蘋果和封閉性,你可能會或可能不會得到蘋果開發者論壇堅實的答案(私人)。

相關問題