从 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 等的映射中查找它们。
但事实并非如此。
这是我尝试过的和我知道的:
在客户端打印值:console.log(clampedBoard[0])
在 Chrome 的控制台上返回一个 [] 看起来 null/undefined 的字符。
在服务器端,初始化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]};
我有一个节点服务器 运行,在服务器中我生成并存储到 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 等的映射中查找它们。
但事实并非如此。
这是我尝试过的和我知道的:
在客户端打印值:
console.log(clampedBoard[0])
在 Chrome 的控制台上返回一个 [] 看起来 null/undefined 的字符。在服务器端,初始化
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]};