2017-04-09 34 views
0

執行toDataURL後,我借鑑的圖像(本地文件)的畫布,我試着將它與命令ctx.canvas.toDataURL("image/png")Failto上HTMLCanvasElement

出口,但有一個錯誤:

DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 

我已經搜查在谷歌。他們說這是Cross的問題。所以,我加了命令:

image.crossOrigin = '*'; 

但是這對我的項目沒用。其實,我的項目是建立在沒有任何服務器的本地。所以,我不知道爲什麼存在跨域問題。

function loadImageAsync(url) { 
return new Promise(function(resolve, reject) { 
    var image = new Image(); 
    image.onload = function() { 
     image.crossOrigin = '*'; 
     resolve(image); 
    }; 
    image.onerror = function() { 
     reject(new Error('Could not load image at ' + url)); 
    }; 
    image.src = url; 
}); 


    generate() { 
    var p1 = loadImageAsync(this.textures[1]); 
    var p2 = loadImageAsync(this.textures[2]); 
    var p3 = loadImageAsync(this.textures[3]); 
    var ctx = document.createElement("canvas") 
     .getContext("2d"); 
    ctx.canvas.width = this.width; 
    ctx.canvas.height = this.height; 
    var rows = ~~(this.width/70); 
    var cols = ~~(this.height/70); 
    Promise.all([p1, p2, p3]) 
     .then(imgs => { 
      for (let x = 0, i = 0; i < rows; x += 70, i++) { 
       for (let y = 630, j = 0; j < cols; y -= 70, j++) { 
        this.resource[i].forEach(item => { 
         switch (item) { 
          case 1: 
           ctx.drawImage(imgs[0], x, y, 70, 70); 
           break; 
          case 2: 
           ctx.drawImage(imgs[1], x, y, 70, 70); 
           break; 
          case 3: 
           ctx.drawImage(imgs[2], x, y, 70, 70); 
           break; 
          default: 
         } 
        }); 
       } 
      } 
      //window.ctx = ctx; 
      this.image.crossOrigin = '*'; 
      this.image.src = ctx.canvas.toDataURL("image/png"); 
     }); 
}; 
+0

您是否正在從不同的網站載入圖片? –

+0

@moáois我試圖從本地或服務器加載圖像。有相同的問題 –

+0

你運行任何服務器像XAMPP或WAMP? –

回答

1

您需要爲onload函數外的圖像設置crossOrigin

return new Promise(function(resolve, reject) { 
    var image = new Image(); 
    image.crossOrigin = '*'; //<-- set here 
    image.onload = function() { 
     resolve(image); 
    }; 
    image.onerror = function() { 
     reject(new Error('Could not load image at ' + url)); 
    }; 
    image.src = url; 
}); 
+0

是的,這僅適用於服務器上的映像。 –

+0

是不是你想要的? –

+0

是啊,它現在爲我的網站上的圖像工作。但對於本地失敗,還有另一個問題。但無論如何,它的工作。 Thx太多了! –

0

當您加載圖像時,如果它們來自另一個域,則它們將被標記爲跨域,除非它們具有CORS權限。這包括從file://加載文件。如果使用canvas 2d,跨域沒有CORS權限的域圖像將會污染畫布,並且如果使用WebGL則根本無法使用

如果文件是本地的,則最好使用簡單的服務器。 Here's onehere's a bunch more

如果圖像實際上是跨域的,那麼您需要通過設置img.crossOrigin來請求CORS權限,並且服務器需要爲圖像返回正確的標頭。我相信,唯一需要的頭部是

Access-Control-Allow-Origin: * 

你必須設置img.crossOrigin之前設置的img.src。設置img.crossOrigin告訴瀏覽器向服務器請求許可。該請求在您設置img.src的那一刻發送。

讓我們嘗試它,我碰巧知道一個imgur URL支持CORS,你所提到的也是你的網址,以及一個從我的網站,我知道不支持CORS

[ 
 
    { url: "https://i.imgur.com/TSiyiJv.jpg", crossOrigin: "*", }, 
 
    { url: "https://newmario.herokuapp.com/img/grassMid.png", crossOrigin: "*", }, 
 
    { url: "https://greggman.com/images/echidna.jpg", /* NO CORS */ }, 
 
].forEach(loadImage); 
 

 
function loadImage(info) { 
 
    const url = info.url; 
 
    const img = new Image() 
 
    img.onload = function() { 
 
    const ctx = document.createElement("canvas").getContext("2d"); 
 
    try { 
 
     ctx.drawImage(img, 0, 0); 
 
     ctx.canvas.toDataURL(); 
 
     log("got CORS permission for:", url); 
 
    } catch(e) { 
 
     log("**NO** CORS permission for:", url); 
 
    } 
 
    } 
 
    img.onerror = function() { 
 
    log("could not load image:", url); 
 
    } 
 
    img.crossOrigin = info.crossOrigin; 
 
    img.src = url; 
 
} 
 

 
function log(...args) { 
 
    const elem = document.createElement("pre"); 
 
    elem.textContent = [...args].join(' '); 
 
    document.body.appendChild(elem); 
 
}
pre { margin: 0; }

我的成績,imgur形象工程,你的工作,我的不(預期)

注意,有8例

| local/remote | crossOrigin | CORS headers | Result 
-+-----------------+---------------+---------------+--------------------- 
1| local   | not set  |  no  | can use image 
-+-----------------+---------------+---------------+---------------------- 
2| local   | not set  |  yes  | can use image 
-+-----------------+---------------+---------------+---------------------- 
3| local   | set   |  no  | image fails to load 
-+-----------------+---------------+---------------+---------------------- 
4| local   | set   |  yes  | can use image 
-+-----------------+---------------+---------------+---------------------- 
5| remote  | not set  |  no  | can use image in canvas 2d 
|     |    |    | but it will dirty the canvas. 
|     |    |    | Can't use with WebGL 
-+-----------------+---------------+---------------+---------------------- 
6| remote  | not set  |  yes  | can use image in canvas 2d 
|     |    |    | but it will dirty the canvas 
|     |    |    | Can't use with WebGL 
-+-----------------+---------------+---------------+----------------------  
7| remote  | set   |  no  | image fails to load 
-+-----------------+---------------+---------------+----------------------  
8| remote  | set   |  yes  | can use image 
-+-----------------+---------------+---------------+---------------------- 
+0

我也爲圖像構建服務器,https://newmario.herokuapp.com/img/grassMid.png,但它不起作用 –

+0

我修改了標頭:var allowCrossDomain = function(req,res,next){ res。 header('Access-Control-Allow-Origin','*'); ('Access-Control-Allow-Methods','GET,PUT,POST,DELETE'); res.header('Access-Control-Allow-Headers','*'); next(); } –

+0

這是爲我工作。請參閱示例 – gman

相關問題