Merge pull request #565 from btsimonh/btsimonh-async-resize

Add Async to Matix.resize
This commit is contained in:
Peter Braden 2017-11-03 10:41:29 +01:00 committed by GitHub
commit d760e792a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 167 additions and 15 deletions

34
examples/async-resize.js Normal file
View File

@ -0,0 +1,34 @@
var cv = require('../lib/opencv');
cv.readImage("./files/mona.png", function(err, im) {
if (err) throw err;
var width = im.width();
var height = im.height();
if (width < 1 || height < 1) throw new Error('Image has no size');
console.log('Image loaded from ./files/mona.png at '+im.width()+'x'+im.height());
var AfterResize = function(err, img){
if (err){
console.log('Error in resize:' + err);
return;
}
img.save("./tmp/resize-async-image.png");
console.log('Image saved to ./tmp/resize-async-image.png at '+img.width()+'x'+img.height());
};
var newwidth = width*0.95;
var newheight = height*0.95;
var Async = true;
if (Async){
// note - generates a new image
im.resize(newwidth, newheight, AfterResize);
} else {
// sync - note - modifies the input image
im.resize(newwidth, newheight);
AfterResize(null, im);
}
});

View File

@ -1889,27 +1889,145 @@ cv::Rect* setRect(Local<Object> objRect, cv::Rect &result) {
return &result; return &result;
} }
NAN_METHOD(Matrix::Resize) {
class ResizeASyncWorker: public Nan::AsyncWorker {
public:
ResizeASyncWorker(Nan::Callback *callback, Matrix *image, cv::Size size, double fx, double fy, int interpolation) :
Nan::AsyncWorker(callback),
image(image),
size(size),
fx(fx),
fy(fy),
interpolation(interpolation),
success(0){
}
~ResizeASyncWorker() {
}
void Execute() {
try {
dest = new Matrix();
cv::resize(image->mat, dest->mat, size, fx, fy, interpolation);
success = 1;
} catch(...){
success = 0;
}
}
void HandleOKCallback() {
Nan::HandleScope scope; Nan::HandleScope scope;
if (success){
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 = dest->mat;
delete dest;
//delete dest;
Local<Value> argv[] = {
Nan::Null(), // err
im_to_return //result
};
Nan::TryCatch try_catch;
callback->Call(2, argv);
if (try_catch.HasCaught()) {
Nan::FatalException(try_catch);
}
} else {
delete dest;
Local<Value> argv[] = {
Nan::New("C++ exception").ToLocalChecked(), // err
Nan::Null() //result
};
Nan::TryCatch try_catch;
callback->Call(2, argv);
if (try_catch.HasCaught()) {
Nan::FatalException(try_catch);
}
}
}
private:
Matrix *image;
Matrix *dest;
cv::Size size;
double fx;
double fy;
int interpolation;
int success;
};
NAN_METHOD(Matrix::Resize) {
SETUP_FUNCTION(Matrix)
if (info.Length() < 2) {
return Nan::ThrowError("Matrix.resize requires at least 2 argument2");
}
//im.resize( width, height );
//im.resize( width, height, fx, fy );
//im.resize( width, height, interpolation );
//im.resize( width, height, fx, fy, interpolation );
// if fn is added on the end, makes it Async
int numargs = info.Length();
int isAsync = 0;
if (info[numargs-1]->IsFunction()){
isAsync = 1;
}
if (info.Length() < 2+isAsync) {
return Nan::ThrowError("Matrix.resize requires at least x and y size argument2");
}
int x = info[0]->Uint32Value(); int x = info[0]->Uint32Value();
int y = info[1]->Uint32Value(); int y = info[1]->Uint32Value();
/*
CV_INTER_NN =0,
CV_INTER_LINEAR =1,
CV_INTER_CUBIC =2,
CV_INTER_AREA =3,
CV_INTER_LANCZOS4 =4
*/
int interpolation = (info.Length() < 3) ? (int)cv::INTER_LINEAR : info[2]->Uint32Value();
cv::Size size(x, y);
if (size.area() == 0) {
return Nan::ThrowError("Area of size must be > 0");
}
double fx = 0;
double fy = 0;
int interpolation = cv::INTER_LINEAR;
// if 4 or more args, then expect fx, fy next
if (numargs >= 4+isAsync) {
DOUBLE_FROM_ARGS(fx, 2)
DOUBLE_FROM_ARGS(fy, 3)
if (numargs == 5+isAsync) {
INT_FROM_ARGS(interpolation, 5)
}
} else {
// if 3 args after possible function, expect interpolation
if (numargs == 3+isAsync) {
INT_FROM_ARGS(interpolation, 3)
}
}
// if async
if (isAsync){
REQ_FUN_ARG(numargs-1, cb);
Nan::Callback *callback = new Nan::Callback(cb.As<Function>());
Nan::AsyncQueueWorker(new ResizeASyncWorker(callback, self, size, fx, fy, interpolation));
info.GetReturnValue().Set(Nan::Null());
} else {
Matrix *self = Nan::ObjectWrap::Unwrap<Matrix>(info.This()); Matrix *self = Nan::ObjectWrap::Unwrap<Matrix>(info.This());
cv::Mat res = cv::Mat(x, y, CV_32FC3); cv::Mat res = cv::Mat(x, y, CV_32FC3);
cv::resize(self->mat, res, cv::Size(x, y), 0, 0, interpolation); cv::resize(self->mat, res, cv::Size(x, y), 0, 0, interpolation);
~self->mat; ~self->mat;
self->mat = res; self->mat = res;
}
return;
} }
NAN_METHOD(Matrix::Rotate) { NAN_METHOD(Matrix::Rotate) {