Dav*_*das 6 javascript c++ add-on node.js node-webkit
我正在用C++编写一个node-webkit插件来解码图像数据并将一组像素数据返回给调用者.以下代码(为简洁而删节)工作得很好:
caller.js
var image_data = canvas_context.createImageData(w, h);
var addon = require('decoder.node');
var decoder = new addon.Decoder();
var pixel_array = decoder.getPixelArray();
image_data.data.set(pixel_array);
canvas_context.putImageData(image_data);
Run Code Online (Sandbox Code Playgroud)
decoder.cpp
Handle<Value> Decoder::getPixelArray(const Arguments &args) {
HandleScope scope;
// unwrap self
DecoderObj *obj = ObjectWrap::Unwrap<DecoderObj>(args.This());
if (obj == NULL) return scope.Close(Number::New(1));
// get pointer to pixel data
PixelPtr *ptr = NULL;
uint64_t len = 0;
obj->GetPixelsPtr((PixelPtr*)&ptr, &len);
// create javascript native array
// from http://luismreis.github.io/node-bindings-guide/docs/returning.html
v8::Handle<Value> fun_val = Context::GetCurrent()->Global()->Get(String::New("Uint8ClampedArray"));
v8::Handle<Function> fun = v8::Handle<Function>::Cast(fun_val);
const unsigned argc = 1;
Local<Value> argv[argc] = { Local<Value>::New(Uint32::New(len)) };
Local<v8::Object> array = fun->NewInstance(argc, argv);
// populate js native array with pixel ptr data
array->SetIndexedPropertiesToExternalArrayData(ptr, v8::kExternalUnsignedByteArray, len);
// return native array to javascript caller
return scope.Close(array);
}
Run Code Online (Sandbox Code Playgroud)
唯一的问题是调用者调用ImageData对象上的set()方法.事实证明这是不可接受的慢(即> = 20ms).我认为缓慢是由于大量数据从一个内存位置复制到另一个内存位置.所以我想我会尝试通过将对ImageData对象的引用传递到插件来解决这个问题,然后让插件直接写入对象,从而无需内存复制.不幸的是,我无法让这个工作.这是修改后的代码不起作用:
caller.js
var image_data = canvas_context.createImageData(w, h);
var addon = require('decoder.node');
var decoder = new addon.Decoder();
decoder.getPixelArray(image_data.data);
canvas_context.putImageData(image_data);
Run Code Online (Sandbox Code Playgroud)
decoder.cpp
Handle<Value> Decoder::getPixelArray(const Arguments &args) {
HandleScope scope;
// unwrap self
DecoderObj *obj = ObjectWrap::Unwrap<DecoderObj>(args.This());
if (obj == NULL) return scope.Close(Number::New(1));
// convert image_data arg into local array
Local<Array> array = Array::Cast(*args[0]);
// get pointer to pixel data
PixelPtr *ptr = NULL;
uint64_t len = 0;
obj->GetPixelsPtr((PixelPtr*)&ptr, &len);
// populate image_data array with pixel ptr data
array->SetIndexedPropertiesToExternalArrayData(ptr, v8::kExternalUnsignedByteArray, len);
}
Run Code Online (Sandbox Code Playgroud)
我知道这不起作用,因为putImageData()导致黑框,而原始代码成功地绘制了预期的实际框架.
这是我的问题:是否可以在JavaScript中创建一个ImageData对象和/或Uint8ClampedArray,通过引用将它传递给Node.js插件,让addon写入对象的内存位置,然后就可以使用该对象了JavaScript上下文没有执行内存复制??
我不知道我做错了,还是不可能,或者两者兼而有之.:)