从 Javascript Uint8ClampedArray 获取位

Getting bits from Javascript Uint8ClampedArray

我有一个节点服务器 运行,在服务器中我生成并存储到 Redis 中,这些位表示 canvas 上的颜色。存储位中的每四位代表一种 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]>>4,和 clampedBoard[0]&15 来得到那些两种颜色,然后我可以 在键为 0000、0001 等的映射中查找它们。

但事实并非如此。

这是我尝试过的和我知道的:

  1. 在客户端打印值:console.log(clampedBoard[0]) 在 Chrome 的控制台上返回一个 [] 看起来 null/undefined 的字符。

  2. 在服务器端,初始化byteArr的时候把前160个值清0,我手动设置前8位为'00111111',也就是二进制表示ASCII 字符 '?'.

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

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

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

首先,你可以做:

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

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

此外,按照您将其传递给对象的方式,"stringification" 会将其转换为字符串而不是数组。为了获得数组,您需要从 ArrayBuffer 中创建一个 Node.js' 缓冲区,然后将其转换为原生数组,如下所示:

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