簡體   English   中英

在畫布中操縱像素

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM