Files
opencv/cxx/videocap.cc
2025-03-17 15:56:50 +08:00

114 lines
4.0 KiB
C++

#include <iostream>
#include <vector>
#include "node.h"
#include "mat.h"
#include "videocap.h"
using namespace Napi;
#define MAT_INSTANCE_METHOD(method) InstanceMethod<&CVVideoCapture::method>(#method, static_cast<napi_property_attributes>(napi_writable | napi_configurable))
#define MAT_STATIC_METHOD(method) StaticMethod<&CVVideoCapture::method>(#method, static_cast<napi_property_attributes>(napi_writable | napi_configurable))
FunctionReference *CVVideoCapture::constructor = nullptr;
Napi::Object CVVideoCapture::Init(Napi::Env env, Napi::Object exports)
{
Function func = DefineClass(env, "VideoCapture", {
MAT_INSTANCE_METHOD(Open),
MAT_INSTANCE_METHOD(IsOpened),
MAT_INSTANCE_METHOD(Grab),
MAT_INSTANCE_METHOD(Retrieve),
MAT_INSTANCE_METHOD(Read),
MAT_INSTANCE_METHOD(Set),
MAT_INSTANCE_METHOD(Get),
MAT_INSTANCE_METHOD(GetBackendName),
});
constructor = new FunctionReference();
*constructor = Napi::Persistent(func);
exports.Set("VideoCapture", func);
env.SetInstanceData<FunctionReference>(constructor);
return exports;
}
CVVideoCapture::CVVideoCapture(const Napi::CallbackInfo &info)
: ObjectWrap<CVVideoCapture>(info)
{
if (info[0].IsString()) {
auto apiPreference = (info.Length() > 1) ? info[1].As<Number>().Int32Value() : cv::CAP_ANY;
std::vector<int> params;
if (info.Length() > 2) {
auto paramsArray = info[2].As<Array>();
params.resize(paramsArray.Length());
for (auto i = 0; i < params.size(); ++i) params[i] = paramsArray.Get(i).As<Number>().Int32Value();
}
capture_ = cv::VideoCapture(info[0].As<String>().Utf8Value(), apiPreference, params);
}
else if (info[0].IsNumber()) {
auto index = info[0].As<Number>().Int32Value();
auto apiPreference = (info.Length() > 1) ? info[1].As<Number>().Int32Value() : cv::CAP_ANY;
std::vector<int> params;
if (info.Length() > 2) {
auto paramsArray = info[2].As<Array>();
params.resize(paramsArray.Length());
for (auto i = 0; i < params.size(); ++i) params[i] = paramsArray.Get(i).As<Number>().Int32Value();
}
capture_ = cv::VideoCapture(index, apiPreference, params);
}
else capture_ = cv::VideoCapture();
}
Napi::Value CVVideoCapture::Open(const Napi::CallbackInfo &info)
{
bool res = false;
auto apiPreference = (info.Length() > 1) ? info[1].As<Number>().Int32Value() : cv::CAP_ANY;
std::vector<int> params;
if (info.Length() > 2) {
auto paramsArray = info[2].As<Array>();
params.resize(paramsArray.Length());
for (auto i = 0; i < params.size(); ++i) params[i] = paramsArray.Get(i).As<Number>().Int32Value();
}
if (info[0].IsString()) res = capture_.open(info[0].As<String>().Utf8Value(), apiPreference, params);
else if (info[0].IsNumber()) res = capture_.open(info[0].As<Number>().Int32Value(), apiPreference, params);
return Boolean::New(info.Env(), res);
}
Napi::Value CVVideoCapture::IsOpened(const Napi::CallbackInfo &info)
{
return Boolean::New(info.Env(), capture_.isOpened());
}
Napi::Value CVVideoCapture::Grab(const Napi::CallbackInfo &info)
{
return Boolean::New(info.Env(), capture_.grab());
}
Napi::Value CVVideoCapture::Retrieve(const Napi::CallbackInfo &info)
{
auto flag = info[0].As<Number>().Int32Value();
return CVMat::CreateMat(info.Env(), [&](CVMat &mat) {
capture_.retrieve(mat.mat_, flag);
});
}
Napi::Value CVVideoCapture::Read(const Napi::CallbackInfo &info)
{
return CVMat::CreateMat(info.Env(), [&](CVMat &mat) {
capture_.read(mat.mat_);
});
}
Napi::Value CVVideoCapture::Set(const Napi::CallbackInfo &info)
{
capture_.set(info[0].As<Number>().Int32Value(), info[1].As<Number>().DoubleValue());
return info.Env().Undefined();
}
Napi::Value CVVideoCapture::Get(const Napi::CallbackInfo &info)
{
return Number::New(info.Env(), capture_.get(info[0].As<Number>().Int32Value()));
}
Napi::Value CVVideoCapture::GetBackendName(const Napi::CallbackInfo &info)
{
return String::New(info.Env(), capture_.getBackendName());
}
void InitVideoCaptureAPI(Napi::Env env, Napi::Object exports)
{
CVVideoCapture::Init(env, exports);
}