У меня есть данные изображения холста:
myImage = ctx.getImageData(0, 0, 640, 480);
Я понял, что я могу создавать новые Uint8Array
и использовать set()
скопировать imagedata. Это рабочий пример:
var numBytes = width * height * 4;
var ptr= Module._malloc(numBytes);
var heapBytes= new Uint8Array(Module.HEAPU8.buffer, ptr, numBytes);
heapBytes.set(new Uint8Array(myImage.data));
_processImage(heapBytes.byteOffset, width, height);
myImage.data.set(heapBytes);
Но, к сожалению, каждый .set()
операция выполняется намного медленнее, чем обработка изображения, а приведенный выше код работает медленнее, чем реализация JS!
Итак, я хочу обработать изображение, не копируя его. Я могу успешно читать и записывать данные прямо в кучу следующим образом:
Module.HEAPU8.set(myImage.data, myImage.data.byteOffset);
_processImage(myImage.data.byteOffset, width, height);
myImage.data.set(new Uint8ClampedArray(Module.HEAPU8.buffer , myImage.data.byteOffset , numBytes));
Это быстрее, но все еще первый .set()
занимает 17 мс, чтобы выполнить.
Прототип функции c ++:
extern "C" {
int processImage(unsigned char *buffer, int width, int height)
{
}
}
Есть ли способ передать массив в C ++ без использования set()
? Просто сказать С ++, где данные находятся в памяти, и разрешить их модифицировать?
Просто сказать С ++, где данные находятся в памяти, и разрешить их модифицировать?
Начиная с версии 1.34.12, Emscripten имеет SPLIT_MEMORY опция, где вы можете указать Emscripten использовать существующий буфер как часть его пространства памяти, которое разделено на куски одинакового размера
Вы могли бы, например, получить буфер с холста
var existingBuffer = myImage.data.buffer;
var bufferSize = existingBuffer.byteLength; // Must be equal to SPLIT_MEMORY
а затем, модифицируя пример из объяснение разделения памяти, скажите Emscripten использовать этот буфер как часть своего пространства памяти
var chunkIndex = 2; // For example
allocateSplitChunk(chunkIndex, existingBuffer);
и затем передайте указатель на блок вашей функции C ++.
var pointerToImageInGlobalMemorySpace = chunkIndex * bufferSize;
_processImage(pointerToImageInGlobalMemorySpace, width, height);
тем не мение есть проблемы и ограничения
Других решений пока нет …