image - 使用 Go WebAssembly 访问 ImageData.data
问题描述
我想在 Go 中编写一个照片过滤器以将其用作 WebAssembly 模块。
Go 有类型js.Value
。我可以Get
, Set
,Index
就Call
可以了。但是如何ImageData.data
快速使用 Go 中的像素数组呢?data.Index(index).Int()
使用and之类的东西.SetIndex(..., ...)
非常慢。我没有检查,如果这得到正确的结果。
第一次尝试非常慢(大约比 JS 或 Rust 慢 50 倍):
func Convolve(canvas js.Value, matrix []float64, factor float64) {
side := int(math.Sqrt(float64(len(matrix))))
halfSide := int(side / 2)
context := canvas.Call("getContext", "2d")
source := context.Call("getImageData", 0.0, 0.0, canvas.Get("width").Int(), canvas.Get("height").Int())
sourceData := source.Get("data")
imageWidth := source.Get("width").Int()
imageHeight := source.Get("height").Int()
output := context.Call("createImageData", imageWidth, imageHeight)
outputData := output.Get("data")
for y := 0; y < imageHeight; y++ {
for x := 0; x < imageWidth; x++ {
outputIndex := (y * imageWidth + x) * 4
r := 0.0
g := 0.0
b := 0.0
for cy := 0; cy < side; cy++ {
for cx := 0; cx < side; cx++ {
scy := y + cy - halfSide
scx := x + cx - halfSide
if scy >= 0 && scy < imageHeight && scx >= 0 && scx < imageWidth {
sourceIndex := (scy * imageWidth + scx) * 4
modify := matrix[cy * side + cx]
r += sourceData.Index(sourceIndex).Float() * modify
g += sourceData.Index(sourceIndex + 1).Float() * modify
b += sourceData.Index(sourceIndex + 2).Float() * modify
}
}
}
outputData.SetIndex(outputIndex, r * factor)
outputData.SetIndex(outputIndex + 1, g * factor)
outputData.SetIndex(outputIndex + 2, b * factor)
outputData.SetIndex(outputIndex + 3, sourceData.Index(outputIndex + 3))
}
}
context.Call("putImageData", output, 0, 0);
}
解决方案
Go 1.13(尚未发布)添加了 2 个函数syscall/js
,允许您复制整个数组,因此您不必恢复调用Index()
和SetIndex()
每个像素的每个组件!
tip
您可以在当前看到它们:
https://tip.golang.org/pkg/syscall/js/#CopyBytesToGo
https://tip.golang.org/pkg/syscall/js/#CopyBytesToJS
所以基本上你可以做的是首先将整个图像数据复制到一个 Go 字节切片中,然后在 Go 中使用它(进行过滤),一旦你完成,复制回改变的切片。它只需要 2 个js
系统调用。
推荐阅读
- javascript - 返回一个新的承诺,加强了备用承诺
- javascript - 如何过滤来自 API 的数据并按年和月存储在数组中?
- javascript - Gnome Shell 样式表
- sql - SQL如何为这个问题创建一个聚合?
- java - Spring Cloud Gateway CORS 问题仅适用于 Docker
- javascript - 如何在xml中获取当前公司。奥多 14
- ios - iOS WKWebView 检测网页布局或内容更新
- html - CSS中的元素位置 - 响应式
- azure-functions - Azure Functions Application Insights 日志流未显示日志条目,但实际日志确实显示在事务搜索中
- xml - 使用新属性扩展公共 XSD 架构