Skip to content

Commit 262629e

Browse files
committed
add new needed files
1 parent 7d4d4a5 commit 262629e

File tree

5 files changed

+186
-4
lines changed

5 files changed

+186
-4
lines changed

.gitignore

-3
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ examples/src/AgeGender/age_net.caffemodel
4040
.pnpm-debug.log
4141
examples/data/dnn/yolo-object-detection/
4242
lib/src/*.map
43-
lib/cvloader.js
44-
lib/opencv4nodejs.js
45-
lib/promisify.js
4643
lib/src/*.js
4744
examples/src/JPEGImages/
4845
examples/labels/

install/compileLib.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { type OpencvModule, OpenCVBuilder, OpenCVBuildEnv, type OpenCVBuildEnvPa
22
import child_process from 'child_process'
33
import fs from 'fs'
44
import log from 'npmlog'
5-
import { resolvePath } from '../lib/commons'
5+
import { resolvePath } from '../lib/commons.js'
66
import pc from 'picocolors'
77
import path from 'path'
88
import { EOL } from 'os'

lib/cvloader.js

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
exports.getOpenCV = void 0;
7+
const opencv_build_1 = require("@u4/opencv-build");
8+
const fs_1 = __importDefault(require("fs"));
9+
const path_1 = __importDefault(require("path"));
10+
const commons_1 = require("./commons");
11+
const picocolors_1 = __importDefault(require("picocolors"));
12+
const npmlog_1 = require("npmlog");
13+
const logDebug = process.env.OPENCV4NODES_DEBUG_REQUIRE ? npmlog_1.info : () => { };
14+
function tryGetOpencvBinDir(builder) {
15+
if (process.env.OPENCV_BIN_DIR) {
16+
logDebug('tryGetOpencvBinDir', `${picocolors_1.default.yellow('OPENCV_BIN_DIR')} environment variable is set`);
17+
return process.env.OPENCV_BIN_DIR;
18+
}
19+
// if the auto build is not disabled via environment do not even attempt
20+
// to read package.json
21+
if (!builder.env.isAutoBuildDisabled) {
22+
logDebug('tryGetOpencvBinDir', 'auto build has not been disabled via environment variable, using opencv bin dir of opencv-build');
23+
return builder.env.opencvBinDir;
24+
}
25+
logDebug('tryGetOpencvBinDir', 'auto build has not been explicitly disabled via environment variable, attempting to read envs from package.json...');
26+
// const envs = builder.env.readEnvsFromPackageJson()
27+
if (!builder.env.isAutoBuildDisabled && process.env.OPENCV_BIN_DIR) {
28+
logDebug('tryGetOpencvBinDir', 'auto build has not been disabled via package.json, using opencv bin dir of opencv-build');
29+
return process.env.OPENCV_BIN_DIR; //.opencvBinDir
30+
}
31+
if (builder.env.opencvBinDir) {
32+
logDebug('tryGetOpencvBinDir', 'found opencv binary environment variable in package.json');
33+
return builder.env.opencvBinDir;
34+
}
35+
logDebug('tryGetOpencvBinDir', 'failed to find opencv binary environment variable in package.json');
36+
return null;
37+
}
38+
function getOpenCV(opt) {
39+
if (!opt)
40+
opt = { prebuild: 'latestBuild' };
41+
const builder = new opencv_build_1.OpenCVBuilder(opt);
42+
let opencvBuild = null;
43+
let requirePath = '';
44+
if ((0, commons_1.isElectronWebpack)()) {
45+
requirePath = '../build/Release/opencv4nodejs.node';
46+
}
47+
else {
48+
requirePath = path_1.default.join(__dirname, '../build/Debug/opencv4nodejs.node');
49+
if (!fs_1.default.existsSync(requirePath)) {
50+
requirePath = path_1.default.join(__dirname, '../build/Release/opencv4nodejs.node');
51+
}
52+
requirePath = requirePath.replace(/\.node$/, '');
53+
// path.join(__dirname, process.env.BINDINGS_DEBUG ? '../build/Debug/opencv4nodejs' : '../build/Release/opencv4nodejs')
54+
}
55+
try {
56+
logDebug('require', `require path is ${picocolors_1.default.yellow(requirePath)}`);
57+
opencvBuild = require(requirePath);
58+
}
59+
catch (err) {
60+
// err.code === 'ERR_DLOPEN_FAILED'
61+
logDebug('require', `failed to require cv with exception: ${picocolors_1.default.red(err.toString())}`);
62+
logDebug('require', 'attempting to add opencv binaries to path');
63+
if (!process.env.path) {
64+
logDebug('require', 'there is no path environment variable, skipping...');
65+
throw err;
66+
}
67+
const opencvBinDir = tryGetOpencvBinDir(builder);
68+
logDebug('require', 'adding opencv binary dir to path: ' + opencvBinDir);
69+
if (!fs_1.default.existsSync(opencvBinDir)) {
70+
throw new Error('opencv binary dir does not exist: ' + opencvBinDir);
71+
}
72+
// ensure binaries are added to path on windows
73+
if (!process.env.path.includes(opencvBinDir)) {
74+
process.env.path = `${process.env.path};${opencvBinDir};`;
75+
}
76+
logDebug('require', 'process.env.path: ' + process.env.path);
77+
try {
78+
opencvBuild = require(requirePath);
79+
}
80+
catch (e) {
81+
if (e instanceof Error) {
82+
let msg = '';
83+
const message = e.message;
84+
if (message.startsWith('Cannot find module')) {
85+
msg = `require("${picocolors_1.default.yellow(requirePath)}");
86+
Failed with: ${picocolors_1.default.red(message)}, openCV binding not available, reed:
87+
build-opencv --help
88+
And build missing file with:
89+
npx build-opencv --version 4.6.0 rebuild
90+
91+
PS: a 'npm link' may help
92+
`;
93+
}
94+
else if (message.startsWith('The specified module could not be found.')) {
95+
msg = `require("${picocolors_1.default.yellow(requirePath)}");
96+
Failed with: ${picocolors_1.default.red(message)}, openCV module looks broken, clean you builds directory and rebuild everything
97+
rm -r <path to your build directory>
98+
npx build-opencv --version 4.6.0 rebuild
99+
`;
100+
}
101+
else {
102+
msg = `require("${picocolors_1.default.yellow(requirePath)}");
103+
Failed with: ${picocolors_1.default.red(message)}
104+
`;
105+
}
106+
throw Error(msg);
107+
}
108+
throw e;
109+
}
110+
}
111+
// resolve haarcascade files
112+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
113+
const { haarCascades, lbpCascades } = opencvBuild;
114+
Object.keys(haarCascades).forEach(key => opencvBuild[key] = (0, commons_1.resolvePath)(path_1.default.join(__dirname, 'haarcascades'), haarCascades[key]));
115+
Object.keys(lbpCascades).forEach(key => opencvBuild[key] = (0, commons_1.resolvePath)(path_1.default.join(__dirname, 'lbpcascades'), lbpCascades[key]));
116+
return opencvBuild;
117+
}
118+
exports.getOpenCV = getOpenCV;
119+
exports.default = getOpenCV;

lib/opencv4nodejs.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
const promisify_1 = __importDefault(require("./promisify"));
6+
const src_1 = __importDefault(require("./src"));
7+
const cvloader_1 = require("./cvloader");
8+
function loadOpenCV(opt) {
9+
const cvBase = (0, cvloader_1.getOpenCV)(opt);
10+
if (!cvBase.accumulate) {
11+
throw Error('failed to load opencv basic accumulate not found.');
12+
}
13+
if (!cvBase.blur) {
14+
throw Error('failed to load opencv basic blur not found.');
15+
}
16+
// promisify async methods
17+
let cvObj = (0, promisify_1.default)(cvBase);
18+
cvObj = (0, src_1.default)(cvObj);
19+
// add xmodules alias if not present (moved to C++ part)
20+
// if (!cvObj.xmodules && cvObj.modules)
21+
// cvObj.xmodules = cvObj.modules
22+
return cvObj;
23+
}
24+
const cv = loadOpenCV({ prebuild: 'latestBuild' });
25+
const defExport = { cv };
26+
// duplicate all export for retro-compatibility
27+
for (const key in cv) {
28+
defExport[key] = cv[key];
29+
}
30+
defExport['cv'] = cv;
31+
module.exports = defExport;

lib/promisify.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
const isFn = (obj) => typeof obj === 'function';
4+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5+
const isAsyncFn = (fn) => fn.prototype.constructor.name.endsWith('Async');
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7+
const promisify = (fn) => function (...params) {
8+
if (isFn(params[params.length - 1])) {
9+
return fn.apply(this, params);
10+
}
11+
return new Promise((resolve, reject) => {
12+
const args = Array.prototype.slice.call(params);
13+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
14+
args.push(function (err, res) {
15+
if (err) {
16+
return reject(err);
17+
}
18+
return resolve(res);
19+
});
20+
fn.apply(this, args);
21+
});
22+
};
23+
exports.default = (cv) => {
24+
const fns = Object.keys(cv).filter(k => isFn(cv[k])).map(k => cv[k]);
25+
const asyncFuncs = fns.filter(isAsyncFn);
26+
const clazzes = fns.filter(fn => !!Object.keys(fn.prototype).length);
27+
clazzes.forEach((clazz) => {
28+
const protoFnKeys = Object.keys(clazz.prototype).filter(k => isAsyncFn(clazz.prototype[k]));
29+
protoFnKeys.forEach(k => clazz.prototype[k] = promisify(clazz.prototype[k]));
30+
});
31+
asyncFuncs.forEach((fn) => {
32+
cv[fn.prototype.constructor.name] = promisify(fn);
33+
});
34+
return cv;
35+
};

0 commit comments

Comments
 (0)