node-webkit C++插件可以写入在JavaScript上下文中创建的ImageData对象吗?

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上下文没有执行内存复制??

我不知道我做错了,还是不可能,或者两者兼而有之.:)