mirror of
https://github.com/peterbraden/node-opencv.git
synced 2025-12-08 19:45:55 +00:00
Merge pull request #574 from btsimonh/btsimonh-readImageAsync
Btsimonh read image async
This commit is contained in:
commit
ca7847d651
111
examples/readimage.js
Normal file
111
examples/readimage.js
Normal file
@ -0,0 +1,111 @@
|
||||
var cv = require('../lib/opencv');
|
||||
|
||||
|
||||
// read as a buffer for decode operations later
|
||||
var fs = require('fs');
|
||||
var imgdata = fs.readFileSync("./files/mona.png");
|
||||
|
||||
|
||||
|
||||
var img = cv.readImage("./files/mona.png");
|
||||
console.log('Synchronous readImage("./files/mona.png")'+img.width()+'x'+img.height());
|
||||
|
||||
cv.readImage("./files/mona.png", function(err, im){
|
||||
console.log('callback readImage("./files/mona.png", fn(){})'+im.width()+'x'+im.height());
|
||||
});
|
||||
|
||||
img = cv.readImage( 100, 100 );
|
||||
console.log('Synchronous readImage(100, 100) (create mat)'+img.width()+'x'+img.height()+' type '+img.type());
|
||||
|
||||
cv.readImage(100, 100, function(err, im){
|
||||
console.log('callback readImage(100, 100, fn(){}) (create mat)'+im.width()+'x'+im.height());
|
||||
});
|
||||
|
||||
img = cv.readImage(imgdata);
|
||||
console.log('Synchronous readImage(imgdata:Buffer)'+img.width()+'x'+img.height());
|
||||
|
||||
cv.readImage(imgdata, function(err, im){
|
||||
console.log('callback readImage(imgdata:Buffer, fn(){})'+im.width()+'x'+im.height());
|
||||
});
|
||||
|
||||
|
||||
// try with flags now
|
||||
console.log('Now with flags');
|
||||
|
||||
img = cv.readImage("./files/mona.png", 0);
|
||||
console.log('Synchronous readImage("./files/mona.png", 0) (monochrome)'+img.width()+'x'+img.height()+' type '+img.type());
|
||||
|
||||
cv.readImage("./files/mona.png", 1, function(err, im){
|
||||
console.log('callback readImage("./files/mona.png", 1, fn(){}) (colour)'+im.width()+'x'+im.height()+' type '+im.type());
|
||||
});
|
||||
|
||||
img = cv.readImage( 100, 100, cv.Constants.CV_8UC3 );
|
||||
console.log('Synchronous readImage(100, 100, cv.Constants.CV_8UC3) (create 8 bit 3 channel mat)'+img.width()+'x'+img.height()+' type '+img.type());
|
||||
|
||||
cv.readImage(100, 100, cv.Constants.CV_8UC1, function(err, im){
|
||||
console.log('callback readImage(100, 100, cv.Constants.CV_8UC1, fn(){}) (create mat)'+im.width()+'x'+im.height()+' type '+im.type());
|
||||
});
|
||||
|
||||
img = cv.readImage(imgdata, 0);
|
||||
console.log('Synchronous readImage(imgdata:Buffer, 0) (monochrome)'+img.width()+'x'+img.height()+' type '+img.type());
|
||||
|
||||
cv.readImage(imgdata, 1, function(err, im){
|
||||
console.log('callback readImage(imgdata:Buffer, 1, fn(){}) (colour)'+im.width()+'x'+im.height()+' type '+im.type());
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// try with readImageAsync
|
||||
console.log('Now with readImageAsync');
|
||||
|
||||
img = cv.readImageAsync("./files/mona.png");
|
||||
console.log('Synchronous readImageAsync("./files/mona.png")'+img.width()+'x'+img.height());
|
||||
|
||||
cv.readImageAsync("./files/mona.png", function(err, im){
|
||||
console.log('Asynchronous callback readImageAsync("./files/mona.png", fn(){})'+im.width()+'x'+im.height());
|
||||
});
|
||||
|
||||
img = cv.readImageAsync( 100, 100 );
|
||||
console.log('Synchronous readImageAsync(100, 100) (create mat)'+img.width()+'x'+img.height()+' type '+img.type());
|
||||
|
||||
cv.readImageAsync(100, 100, function(err, im){
|
||||
console.log('!!Synchronous!! callback readImageAsync(100, 100, fn(){}) (create mat)'+im.width()+'x'+im.height());
|
||||
});
|
||||
|
||||
img = cv.readImageAsync(imgdata);
|
||||
console.log('Synchronous readImageAsync(imgdata:Buffer)'+img.width()+'x'+img.height());
|
||||
|
||||
cv.readImageAsync(imgdata, function(err, im){
|
||||
console.log('Asynchronous callback readImageAsync(imgdata:Buffer, fn(){})'+im.width()+'x'+im.height());
|
||||
});
|
||||
|
||||
|
||||
|
||||
// try with flags now
|
||||
console.log('Now Async with flags');
|
||||
|
||||
img = cv.readImageAsync("./files/mona.png", 0);
|
||||
console.log('Synchronous readImageAsync("./files/mona.png", 0) (monochrome)'+img.width()+'x'+img.height()+' type '+img.type());
|
||||
|
||||
cv.readImageAsync("./files/mona.png", 1, function(err, im){
|
||||
console.log('Asynchronous callback readImageAsync("./files/mona.png", 1, fn(){}) (colour)'+im.width()+'x'+im.height()+' type '+im.type());
|
||||
});
|
||||
|
||||
img = cv.readImageAsync( 100, 100, cv.Constants.CV_8UC3 );
|
||||
console.log('Synchronous readImageAsync(100, 100, cv.Constants.CV_8UC3) (create 8 bit 3 channel mat)'+img.width()+'x'+img.height()+' type '+img.type());
|
||||
|
||||
cv.readImageAsync(100, 100, cv.Constants.CV_8UC1, function(err, im){
|
||||
console.log('!!Synchronous!! callback readImageAsync(100, 100, cv.Constants.CV_8UC1, fn(){}) (create mat)'+im.width()+'x'+im.height()+' type '+im.type());
|
||||
});
|
||||
|
||||
img = cv.readImageAsync(imgdata, 0);
|
||||
console.log('Synchronous readImageAsync(imgdata:Buffer, 0) (monochrome)'+img.width()+'x'+img.height()+' type '+img.type());
|
||||
|
||||
cv.readImageAsync(imgdata, 1, function(err, im){
|
||||
console.log('Asynchronous callback readImageAsync(imgdata:Buffer, 1, fn(){}) (colour)'+im.width()+'x'+im.height()+' type '+im.type());
|
||||
});
|
||||
|
||||
console.log('\nTruely Async callbacks should be after this line\n');
|
||||
|
||||
282
src/OpenCV.cc
282
src/OpenCV.cc
@ -11,13 +11,238 @@ void OpenCV::Init(Local<Object> target) {
|
||||
target->Set(Nan::New<String>("version").ToLocalChecked(), Nan::New<String>(out, n).ToLocalChecked());
|
||||
|
||||
Nan::SetMethod(target, "readImage", ReadImage);
|
||||
Nan::SetMethod(target, "readImageAsync", ReadImageAsync);
|
||||
Nan::SetMethod(target, "readImageMulti", ReadImageMulti);
|
||||
}
|
||||
|
||||
|
||||
// worker which decodes an image from data.
|
||||
class AsyncImDecodeWorker: public Nan::AsyncWorker {
|
||||
public:
|
||||
|
||||
AsyncImDecodeWorker(Nan::Callback *callback, uint8_t *buf, unsigned len, int flags = -1):
|
||||
Nan::AsyncWorker(callback),
|
||||
buf(buf),
|
||||
len(len),
|
||||
flags(flags){
|
||||
}
|
||||
|
||||
~AsyncImDecodeWorker() {
|
||||
}
|
||||
|
||||
void Execute() {
|
||||
// Local<Object> img_to_return =
|
||||
// Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked();
|
||||
// img = Nan::ObjectWrap::Unwrap<Matrix>(img_to_return);
|
||||
cv::Mat *mbuf = new cv::Mat(len, 1, CV_64FC1, buf);
|
||||
outputmat = cv::imdecode(*mbuf, flags);
|
||||
}
|
||||
|
||||
void HandleOKCallback() {
|
||||
Nan::HandleScope scope;
|
||||
|
||||
Local<Object> im_to_return= Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked();
|
||||
Matrix *img = Nan::ObjectWrap::Unwrap<Matrix>(im_to_return);
|
||||
img->mat = outputmat;
|
||||
|
||||
Local<Value> argv[] = {
|
||||
Nan::Null(),
|
||||
im_to_return
|
||||
};
|
||||
|
||||
Nan::TryCatch try_catch;
|
||||
callback->Call(2, argv);
|
||||
if (try_catch.HasCaught()) {
|
||||
Nan::FatalException(try_catch);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t *buf;
|
||||
unsigned len;
|
||||
int flags;
|
||||
cv::Mat outputmat;
|
||||
//Matrix *img;
|
||||
};
|
||||
|
||||
|
||||
// worker which reads an image from a file.
|
||||
class AsyncImReadWorker: public Nan::AsyncWorker {
|
||||
public:
|
||||
|
||||
AsyncImReadWorker(Nan::Callback *callback, std::string filename, int flags = CV_LOAD_IMAGE_UNCHANGED):
|
||||
Nan::AsyncWorker(callback),
|
||||
filename(filename),
|
||||
flags(flags) {
|
||||
}
|
||||
|
||||
~AsyncImReadWorker() {
|
||||
}
|
||||
|
||||
void Execute() {
|
||||
outputmat = cv::imread(filename, CV_LOAD_IMAGE_UNCHANGED);
|
||||
}
|
||||
|
||||
void HandleOKCallback() {
|
||||
Nan::HandleScope scope;
|
||||
|
||||
Local<Object> im_to_return= Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked();
|
||||
Matrix *img = Nan::ObjectWrap::Unwrap<Matrix>(im_to_return);
|
||||
img->mat = outputmat;
|
||||
|
||||
Local<Value> argv[] = {
|
||||
Nan::Null(),
|
||||
im_to_return
|
||||
};
|
||||
|
||||
Nan::TryCatch try_catch;
|
||||
callback->Call(2, argv);
|
||||
if (try_catch.HasCaught()) {
|
||||
Nan::FatalException(try_catch);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::string filename;
|
||||
int flags;
|
||||
cv::Mat outputmat;
|
||||
};
|
||||
|
||||
|
||||
|
||||
NAN_METHOD(OpenCV::ReadImageAsync) {
|
||||
Nan::EscapableHandleScope scope;
|
||||
|
||||
Local<Value> argv[2];
|
||||
argv[0] = Nan::Null();
|
||||
argv[1] = Nan::Null();
|
||||
|
||||
int callback_arg = -1;
|
||||
int numargs = info.Length();
|
||||
|
||||
Local<Function> cb;
|
||||
|
||||
// deal with situation where we have int, int, cb
|
||||
if (info[numargs-1]->IsFunction()){
|
||||
callback_arg = numargs-1;
|
||||
cb = Local<Function>::Cast(info[callback_arg]);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
if (info[0]->IsNumber() && info[1]->IsNumber()) {
|
||||
//////////////////////////////
|
||||
// create image from a filename
|
||||
// always do sync as this take no time?
|
||||
int width, height;
|
||||
int type = CV_64FC1;
|
||||
|
||||
// if we have a type arg
|
||||
if ((numargs > 2) && info[2]->IsNumber()){
|
||||
type = info[2]->Uint32Value();
|
||||
}
|
||||
|
||||
width = info[0]->Uint32Value();
|
||||
height = info[1]->Uint32Value();
|
||||
Local<Object> img_to_return =
|
||||
Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked();
|
||||
Matrix *img = Nan::ObjectWrap::Unwrap<Matrix>(img_to_return);
|
||||
img->mat = *(new cv::Mat(width, height, type));
|
||||
if (callback_arg < 0){
|
||||
info.GetReturnValue().Set(img_to_return);
|
||||
return;
|
||||
} else {
|
||||
argv[0] = Nan::Null();
|
||||
argv[1] = img_to_return;
|
||||
cb->Call(Nan::GetCurrentContext()->Global(), 2, argv);
|
||||
return;
|
||||
}
|
||||
// WILL have returned by here unless exception
|
||||
//////////////////////////////
|
||||
|
||||
} else if (info[0]->IsString()) {
|
||||
|
||||
//////////////////////////////
|
||||
// read image from a filename
|
||||
std::string filename = std::string(*Nan::Utf8String(info[0]->ToString()));
|
||||
int flags = CV_LOAD_IMAGE_UNCHANGED;
|
||||
if (numargs > 1){
|
||||
if (info[1]->IsNumber()){
|
||||
flags = info[1]->Uint32Value();
|
||||
}
|
||||
}
|
||||
if (callback_arg < 0){
|
||||
Local<Object> img_to_return =
|
||||
Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked();
|
||||
Matrix *img = Nan::ObjectWrap::Unwrap<Matrix>(img_to_return);
|
||||
img->mat = cv::imread(filename, flags);
|
||||
info.GetReturnValue().Set(img_to_return);
|
||||
return;
|
||||
} else {
|
||||
Nan::Callback *callback = new Nan::Callback(cb.As<Function>());
|
||||
Nan::AsyncQueueWorker(new AsyncImReadWorker(callback, filename, flags));
|
||||
return;
|
||||
}
|
||||
// WILL have returned by here unless exception
|
||||
//////////////////////////////
|
||||
|
||||
} else if (Buffer::HasInstance(info[0])) {
|
||||
//////////////////////////////
|
||||
// read image from a buffer
|
||||
// if sync
|
||||
int flags = CV_LOAD_IMAGE_UNCHANGED;
|
||||
if (numargs > 1){
|
||||
if (info[1]->IsNumber()){
|
||||
flags = info[1]->Uint32Value();
|
||||
}
|
||||
}
|
||||
if (callback_arg < 0){
|
||||
Local<Object> img_to_return =
|
||||
Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked();
|
||||
Matrix *img = Nan::ObjectWrap::Unwrap<Matrix>(img_to_return);
|
||||
uint8_t *buf = (uint8_t *) Buffer::Data(info[0]->ToObject());
|
||||
unsigned len = Buffer::Length(info[0]->ToObject());
|
||||
cv::Mat *mbuf = new cv::Mat(len, 1, CV_64FC1, buf);
|
||||
img->mat = cv::imdecode(*mbuf, flags);
|
||||
info.GetReturnValue().Set(img_to_return);
|
||||
return;
|
||||
} else {
|
||||
// async
|
||||
uint8_t *buf = (uint8_t *) Buffer::Data(info[0]->ToObject());
|
||||
unsigned len = Buffer::Length(info[0]->ToObject());
|
||||
Nan::Callback *callback = new Nan::Callback(cb.As<Function>());
|
||||
Nan::AsyncQueueWorker(new AsyncImDecodeWorker(callback, buf, len, flags));
|
||||
return;
|
||||
}
|
||||
// WILL have returned by here unless exception
|
||||
//////////////////////////////
|
||||
}
|
||||
|
||||
} catch (cv::Exception& e) {
|
||||
argv[0] = Nan::Error(e.what());
|
||||
argv[1] = Nan::Null();
|
||||
}
|
||||
|
||||
Nan::TryCatch try_catch;
|
||||
// if we got a callback
|
||||
if (callback_arg >= 0){
|
||||
// if using callback
|
||||
cb->Call(Nan::GetCurrentContext()->Global(), 2, argv);
|
||||
} else {
|
||||
// can only get here by exception
|
||||
info.GetReturnValue().Set(Nan::New<Boolean>(false));
|
||||
}
|
||||
if (try_catch.HasCaught()) {
|
||||
Nan::FatalException(try_catch);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NAN_METHOD(OpenCV::ReadImage) {
|
||||
Nan::EscapableHandleScope scope;
|
||||
|
||||
REQ_FUN_ARG(1, cb);
|
||||
|
||||
Local<Value> argv[2];
|
||||
argv[0] = Nan::Null();
|
||||
@ -26,45 +251,82 @@ NAN_METHOD(OpenCV::ReadImage) {
|
||||
Matrix *img = Nan::ObjectWrap::Unwrap<Matrix>(im_h);
|
||||
argv[1] = im_h;
|
||||
|
||||
int callback_arg = -1;
|
||||
int numargs = info.Length();
|
||||
int success = 1;
|
||||
|
||||
Local<Function> cb;
|
||||
|
||||
// deal with situation where we have int, int, cb
|
||||
if (info[numargs-1]->IsFunction()){
|
||||
callback_arg = numargs-1;
|
||||
cb = Local<Function>::Cast(info[callback_arg]);
|
||||
}
|
||||
|
||||
try {
|
||||
cv::Mat mat;
|
||||
|
||||
if (info[0]->IsNumber() && info[1]->IsNumber()) {
|
||||
int width, height;
|
||||
|
||||
int type = CV_64FC1;
|
||||
// if we have a type arg
|
||||
if ((numargs > 2) && info[2]->IsNumber()){
|
||||
type = info[2]->Uint32Value();
|
||||
}
|
||||
width = info[0]->Uint32Value();
|
||||
height = info[1]->Uint32Value();
|
||||
mat = *(new cv::Mat(width, height, CV_64FC1));
|
||||
mat = *(new cv::Mat(width, height, type));
|
||||
|
||||
} else if (info[0]->IsString()) {
|
||||
std::string filename = std::string(*Nan::Utf8String(info[0]->ToString()));
|
||||
mat = cv::imread(filename, CV_LOAD_IMAGE_UNCHANGED);
|
||||
int flags = CV_LOAD_IMAGE_UNCHANGED;
|
||||
if (numargs > 1){
|
||||
if (info[1]->IsNumber()){
|
||||
flags = info[1]->Uint32Value();
|
||||
}
|
||||
}
|
||||
mat = cv::imread(filename, flags);
|
||||
|
||||
} else if (Buffer::HasInstance(info[0])) {
|
||||
uint8_t *buf = (uint8_t *) Buffer::Data(info[0]->ToObject());
|
||||
unsigned len = Buffer::Length(info[0]->ToObject());
|
||||
|
||||
int flags = CV_LOAD_IMAGE_UNCHANGED;
|
||||
if (numargs > 1){
|
||||
if (info[1]->IsNumber()){
|
||||
flags = info[1]->Uint32Value();
|
||||
}
|
||||
}
|
||||
cv::Mat *mbuf = new cv::Mat(len, 1, CV_64FC1, buf);
|
||||
mat = cv::imdecode(*mbuf, CV_LOAD_IMAGE_UNCHANGED);
|
||||
|
||||
mat = cv::imdecode(*mbuf, flags);
|
||||
if (mat.empty()) {
|
||||
success = 0;
|
||||
argv[0] = Nan::Error("Error loading file");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
img->mat = mat;
|
||||
} catch (cv::Exception& e) {
|
||||
argv[0] = Nan::Error(e.what());
|
||||
argv[1] = Nan::Null();
|
||||
success = 0;
|
||||
}
|
||||
|
||||
Nan::TryCatch try_catch;
|
||||
cb->Call(Nan::GetCurrentContext()->Global(), 2, argv);
|
||||
|
||||
// if we got a callback
|
||||
if (callback_arg >= 0){
|
||||
// if using callback
|
||||
cb->Call(Nan::GetCurrentContext()->Global(), 2, argv);
|
||||
} else {
|
||||
// if to return the mat
|
||||
if (success)
|
||||
info.GetReturnValue().Set(im_h);
|
||||
else
|
||||
info.GetReturnValue().Set(Nan::New<Boolean>(false));
|
||||
}
|
||||
if (try_catch.HasCaught()) {
|
||||
Nan::FatalException(try_catch);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -86,6 +86,7 @@ public:
|
||||
static void Init(Local<Object> target);
|
||||
|
||||
static NAN_METHOD(ReadImage);
|
||||
static NAN_METHOD(ReadImageAsync);
|
||||
static NAN_METHOD(ReadImageMulti);
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user