将Float32Array转换为缓冲区

时间:2020-01-08 19:34:39

标签: javascript node.js

我试图返回浮点数的二进制数组。 我从geotiff库中获取了Float32Array,但是http只能 返回字符串或缓冲区,所以我必须将其“转换”为缓冲区。

const tiff  = await geotiff.fromUrl(ahnUrl);
const image = await tiff.getImage();
const data  = await image.readRasters(); <-- Is Float32Array
res.writeHead(200, {'Content-Type': 'application/octet-stream'});
var buf = Buffer.allocUnsafe( data.width * data.height );
for ( var y = 0; y < data.height; y++ )
{
  for ( var x = 0; x < data.width; x++ )
  {
    buf.writeFloatLE(data[y*data.width+x]);
  }
}
// buf = Buffer.from(data); <-- does not work
// buf = Buffer.from(data.buffer); neither
res.end(buf);

问题是double for循环,我不希望这样。 理想情况下,没有其他数据副本,而且绝对不是 非常慢的双循环。速度非常关键。

我是javascript / nodejs的新手,但似乎Float32Array是多维的 其长度返回1,但其宽度和高度为1024x1024(按预期)。

'const buf = Buffer.from(data)'的结果是一个单字节长度的缓冲区。

2 个答案:

答案 0 :(得分:1)

我认为您误解了readRasters的返回类型。据我从docs得知,默认情况下它不是Float32Array,而是一个数组数组(每个通道一个,例如R,G和B)。

默认情况下,栅格被划分为每个组件的单独阵列。例如,对于RGB图像,我们将获得三个阵列,一个阵列用于红色,绿色和蓝色。

尝试将{interleave: true}传递到readRasters

如果我们想将所有频段交织成一个大数组,则必须传递interleave:true选项:

此后Buffer.from开始解决问题。

答案 1 :(得分:1)

谢谢,这确实有帮助。 但是,执行Buffer.from(Float32Array)会导致每个浮点缓冲区1字节,而且还会复制数据。 要使其正常工作,您还必须使用此软件包:

let toBuffer = require("typedarray-to-buffer")
function()
{
  const data  = await image.readRasters({interleave:true});
  const buf   = toBuffer(data); <-- Now if contains 1 float, this is 4 bytes long.
}