从Javascript Uint8ClampedArray获取位

时间:2018-12-07 19:36:29

标签: javascript bit

我有一个正在运行的节点服务器,在该服务器中,我生成一堆代表画布上颜色的位并将其存储到Redis中。存储位的每四位代表一种4位颜色。 (例如,如果我存储001001101011111,那么我感兴趣的颜色就是0010、0110、1011和1111)。

var byteArr = new ArrayBuffer(360000);
redis_client.set("board", byteArr);
redis_client.setbit("board", 360000, 0);

// There is some garbage at the beginning of the stored value, so zeroing them out.
for(var i = 0; i < 160; i++){
    redis_client.setbit("board", i, 0);
}

当客户端连接到服务器时,我从Redis获取此字符串,并通过Websocket发送它:

wss.on('connection', function(ws) {
    redis_client.get("board", function (error, result) {
        var initial_send = {"initial_send":true, "board":result};
        ws.send(JSON.stringify(initial_send));
    });

在客户端,我这样看板:

socket.onmessage = function (event) {
    var o = JSON.parse(event.data);
    board = o["board"];                                        
    var clampedBoard = new Uint8ClampedArray(board.length); 

    for(var i = 0; i < board.length; i++){                     
        clampedBoard = board[i];                               
    }
}

在这一点上,board的长度为45000,这是因为在Javascript中,最小的TypedArray构造函数仅允许1个字节单位。因此,因为我的初始ArrayBuffer的大小为360000,所以当我在客户端中收到它时,它的大小为360000/8。

这是我遇到问题的地方。此时,如果我得到clampedBoard[0],它应该给我前8位(我关心的前两种颜色),然后我可以执行clampedBoard[0]>>4clampedBoard[0]&15来获得两种颜色,然后我可以 在键为0000、0001等的地图中查找它们。

但这不是正在发生的事情。

这就是我尝试过的,我知道的:

  1. 在客户端打印出值:console.log(clampedBoard[0])在Chrome的控制台上返回[]看起来为空/未定义的字符。

  2. 在服务器端,初始化byteArr并将前160个值清除为0时,我将前8位手动设置为'00111111',这是ASCII字符'?的二进制表示形式。 '。

当在客户端上进行console.logging clampBoard[0]时,我得到相同的[]空/未定义字符,但是当console.logging board[0]时,它打印出一个'?'。我不确定为什么会这样。

当尝试通过执行clampedBoard[0]>>4在我的颜色映射中查找时,它始终默认为字典中表示0的键,即使它应该是0011。

如果我能提供更多信息,请告诉我。

1 个答案:

答案 0 :(得分:0)

首先,您可以执行以下操作:

board = o["board"];                                        
var clampedBoard = new Uint8ClampedArray(board); 

因此您不需要值初始化循环。

此外,按照将其传递给对象的方式,“字符串化”会将其转换为字符串而不是数组。为了获得一个数组,您需要从ArrayBuffer中创建一个Node.js的Buffer,然后将其转换为本地数组,如下所示:

var view = Buffer.from(result); 
var initial_send = {"initial_send":true, "board":[...view]};