How to return cv::Mat in nodejs addon

I’ve written nodejs addon using V8. I’m stuck at a point where I’m trying to return Mat but all I’m getting is corrupted image with size of 2mb (for particular image). Am I doing something wrong? How can I do this using V8?

CPP code snippet

cv::Mat image = ...
std::string my_cv_mat(image.begin<unsigned char>(), image.end<unsigned char>());
args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, my_cv_mat.c_str()).ToLocalChecked());

Nodejs code snippet

// body is express req.body
let bodyBuffer = new Buffer.from(body, "binary");
let detectedFaces = faceDetect.detect(bodyBuffer)  //here I'm reading above Mat image into char string
const out_file = path.basename("output.png")
fs.writeFileSync(out_file, new Buffer.from(detectedFaces, "binary"))

UPDATE

I’ve made update in the code but output image is still not image and its size is now 23mb while it should be 700kb.

CPP updated code snippet

  unsigned int img_size = image.total() * image.elemSize();
  char* image_char = reinterpret_cast<char*>(image.data);
  Nan::MaybeLocal<v8::Object> imageBuffer = Nan::CopyBuffer(image_char, img_size);
  // args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, my_cv_mat.c_str()).ToLocalChecked());
  args.GetReturnValue().Set(imageBuffer.ToLocalChecked());

nodejs code snippet

    let detectedFaces = faceDetect.detect(bodyBuffer)
    const out_file = path.basename("output.png")
    fs.writeFileSync(out_file, new Buffer.from(detectedFaces, "binary"))

Answer

I don’t think a UTF-8 encoded string (or, more accurately: constructing a JavaScript string from raw image data that you’re telling the String constructor to treat as UTF-8 and decode accordingly) is the right tool for the job.

Try creating a Buffer directly in your addon, and returning that as the call’s result (instead of a v8::String).

Leave a Reply

Your email address will not be published. Required fields are marked *