我正在尝试更新画布的图像上下文的ImageData,当我尝试在数据数组中设置元素时,我得到一个错误,指出数组的类型为Js.Typed_array.Uint8ClampedArray.t,而有些东西应该是array('a)。
为什么不能更新JS TypedArray实现?
下面是我的组件代码(为了清晰起见,稍微简化了一些):
let make = _children => {
let map = FeatureMap.make(100, 100);
let (width, height) = map.dimensions;
{...component,
initialState: () => {
map: map,
canvasRef: ref(None)
},
didMount: self => switch (self.state.canvasRef^) {
| None => ()
| Some(canvas) => {
let ctx = getContext2d(canvas);
let imageData = createImageDataCoords(ctx, ~width=float_of_int(width), ~height=float_of_int(height));
let data = Webapi.Dom.Image.data(imageData);
Array.iteri((x, row) => {
Array.iteri((y, weight) => {
let index = (x * width + y) * 4;
let (r, g, b) = weight;
data[index + 0] = r;
data[index + 1] = g;
data[index + 2] = b;
data[index + 3] = 0;
}, row);
}, map.weights);
ctx |> putImageData(imageData, 0., 0., 0., 0., float_of_int(width), float_of_int(height));
}
},
render: _self => <canvas id="weight-map"
width={string_of_int(width)}
height={string_of_int(width)}
ref={_self.handle(setCanvasRef)}></canvas>
};
};发布于 2019-03-17 05:54:40
对于编译器来说,array('a)与Js.Typed_array.Uint8ClampedArray.t不是同一类型,因此它们的操作(包括索引)不能互换。这和你不能把int和float相加的原理是一样的。
要设置类型化数组元素,您需要查找(或编写)允许您显式执行此操作的绑定,而不是使用索引运算符。要做到这一点,你可以查看Js.Typed_array模块-有一个module type S,我们可以把它理解为“所有类型化的数组模块都必须符合这个模块签名”。其中包括Js.Typed_array.Uint8ClampedArray模块。因此,您可以使用S模块类型的unsafe_set函数来设置类型化的数组元素,因为Js.Typed_array.Uint8ClampedArray实现了它:
let module UI8s = Js.Typed_array.Uint8ClampedArray;
UI8s.unsafe_set(data, index, r);
UI8s.unsafe_set(data, index + 1, g);
UI8s.unsafe_set(data, index + 2, b);
UI8s.unsafe_set(data, index + 3, 0);https://stackoverflow.com/questions/55201175
复制相似问题