[英]Manipulating pixels in canvas
我正在嘗試用基於網格的地圖編寫簡單的2D自上而下的游戲,我在某些畫布區域操縱像素時遇到問題。 我有以下功能:
changeCellBackground(x, y, r, g, b){
let cell = this.context.getImageData(x * this.TILE_SIZE, y * this.TILE_SIZE, this.TILE_SIZE, this.TILE_SIZE);
for(let i=0; i<cell.data.length; i+=4){
cell.data[i] += r;
cell.data[i+1] += g;
cell.data[i+2] += b;
}
this.context.putImageData(cell, x * this.TILE_SIZE, y * this.TILE_SIZE);
}
其中context是canvas 2d context:
this.screen = $('#game');
this.context = this.screen[0].getContext('2d');
和Img標簽有src鏈接到tileset:
let tileSet = $('<img></img>').attr('src', '../assets/tiles.png');
但是當我嘗試使用上面的函數時,我得到的是SecurityError: The operation is insecure.
。 據我所知是因為CORS限制的,所以我盡量add crossOrigin="anonymous"
屬性Img
:
let tileSet = $('<img></img>').attr('crossOrigin', 'anonymous').attr('src', '../assets/tiles.png');
但現在我得到了NS_ERROR_NOT_AVAILABLE:
. 我想這是因為當腳本的其余部分開始執行時,圖像還沒有加載。 我該如何解決? 我試過這個:
let tileSet = $('<img></img>');
tileSet.onload = function(){
tileSet.attr('crossOrigin', 'anonymous').attr('src', '../assets/tiles.png');
gameScreen.drawAnimatedImage(0, 0, 'waterfall');
gameScreen.drawAnimatedImage(2, 2, 'fountain');
gameScreen.drawAnimatedImage(11, 5, 'street_lamp');
gameScreen.drawAnimatedImage(10, 5, 'street_lamp');
gameScreen.changeCellBackground(10, 15, -30, -30, -30);
};
但它也沒有工作 - 當我在onload
函數結束時設置console.log(tileSet)
時,控制台上沒有記錄任何內容。 似乎沒有觸發onload函數。 為什么會發生這種情況?我該如何解決這個問題?
這是一種向畫布上的像素添加值的更簡單方法。
你的功能
changeCellBackground(x, y, r, g, b){
將r,g,b添加到拼貼上x,y處的每個像素
可以完成
function changeCellBackground(x, y, r, g, b){
this.context.fillStyle = "rgb(" + Math.floor(r) + "," + Math.floor(g) + "," + Math.floor(b) + ")";
this.context.globalCompositeOperation = "lighter"; // adds the fill color to existing pixels
this.context.fillRect(x * this.TILE_SIZE, y * this.TILE_SIZE, this.TILE_SIZE, this.TILE_SIZE);
this.context.globalCompositeOperation = "source-over"; // restore default composite operation
}
上述功能與您的功能相同,但無需訪問像素數據。 這意味着您不必擔心不安全的圖像,並且可以在沒有交叉原始標題的情況下加載它。
作為猜測,如果您正在使用硬盤驅動器(即../assets/tiles.png
在您的硬盤驅動器上),您將無法獲得CORS映像,因為這需要服務器。
您可以在計算機上設置服務器(有許多選項),然后使用域localhost,在這種情況下,映像不是跨域的,不需要標頭。 或者,您可以查找瀏覽器安全開關並關閉跨源安全性,這樣您也可以訪問圖像數據。
在你的問題中, changeCellBackground()
與tileset
之間沒有任何聯系,所以我不確定是否還有更多問題,但是等待圖像加載,你實際上需要將src部分放在函數之外:
let tileSet = $('<img></img>');
tileSet.onload = function(){
gameScreen.drawAnimatedImage(0, 0, 'waterfall');
gameScreen.drawAnimatedImage(2, 2, 'fountain');
gameScreen.drawAnimatedImage(11, 5, 'street_lamp');
gameScreen.drawAnimatedImage(10, 5, 'street_lamp');
gameScreen.changeCellBackground(10, 15, -30, -30, -30);
};
tileSet.attr('crossOrigin', 'anonymous').attr('src', '../assets/tiles.png');
因為它當前沒有觸發onload事件,因為沒有要加載的src。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.