Может ли add-node C-webkit писать в объект ImageData, созданный в контексте JavaScript?

Я пишу аддон node-webkit в C ++, который декодирует данные изображения и возвращает массив данных пикселей для вызывающей стороны. Следующий код (сокращенно для краткости) работает просто отлично:

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);

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);
}

Единственная проблема заключается в том, что вызывающая сторона вызывает метод set () для объекта ImageData. Это оказалось недопустимо медленным (то есть> = 20 мс). Я предполагаю, что медлительность происходит из-за большого количества данных, копируемых из одной области памяти в другую. Поэтому я решил попытаться исправить это, передав ссылку на объект 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);

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);
}

Я знаю, что это не работает, потому что putImageData () приводит к черной рамке, тогда как исходный код успешно рисует фактическую рамку, как и ожидалось.

Вот мой вопрос: возможно ли создать объект ImageData и / или Uint8ClampedArray в JavaScript, передать его по ссылке в аддон Node.js, сделать надстройку записать в ячейку памяти объекта, а затем иметь возможность использовать объект в контекст JavaScript без выполнения копирования памяти ??

Я не знаю, делаю ли я это неправильно, или это невозможно, или и то, и другое. 🙂

6

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]