增加自动下载
This commit is contained in:
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
简单的OpenCV封装
|
简单的OpenCV封装
|
||||||
|
|
||||||
## 编译源码
|
## 编译源码(可选)
|
||||||
1. 依赖
|
1. 依赖
|
||||||
1. python3
|
1. python3
|
||||||
1. cmake
|
1. cmake
|
||||||
@ -31,6 +31,9 @@ import cv from '@yizhi/opencv';
|
|||||||
|
|
||||||
//配置addon路径
|
//配置addon路径
|
||||||
cv.config("ADDON_PATH", "/path/to/cv.node");
|
cv.config("ADDON_PATH", "/path/to/cv.node");
|
||||||
|
//下载addon(可选)
|
||||||
|
// 如果配置了ADDON_PATH,则下载addon到ADDON_PATH,否则下载到build/cv.node
|
||||||
|
await cv.downloadAddon();
|
||||||
|
|
||||||
//正常使用
|
//正常使用
|
||||||
const im = cv.imread("/path/to/input");
|
const im = cv.imread("/path/to/input");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@yizhi/cv",
|
"name": "@yizhi/cv",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "typing/index.d.ts",
|
"types": "typing/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
|
import path from "path";
|
||||||
import { LINE_8, MARKER_CROSS } from "./consts";
|
import { LINE_8, MARKER_CROSS } from "./consts";
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
ADDON_PATH: "../../build/cv.node",
|
ADDON_PATH: path.join(__dirname, "../../build/cv.node"),
|
||||||
DEFAULT_LINE_TYPE: LINE_8,
|
DEFAULT_LINE_TYPE: LINE_8,
|
||||||
DEFAULT_THICKNESS: 1,
|
DEFAULT_THICKNESS: 1,
|
||||||
DEFAULT_MARKER: MARKER_CROSS,
|
DEFAULT_MARKER: MARKER_CROSS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type AddonConfig = typeof config;
|
||||||
|
|
||||||
export function getAddon() {
|
export function getAddon() {
|
||||||
return require(config.ADDON_PATH);
|
return require(config.ADDON_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getConfig<N extends keyof typeof config>(name: N): typeof config[N] { return config[name]; }
|
export function getConfig<N extends keyof AddonConfig>(name: N): AddonConfig[N] { return config[name]; }
|
||||||
export function setConfig<N extends keyof typeof config>(name: N, value: typeof config[N]) { config[name] = value; }
|
export function setConfig<N extends keyof AddonConfig>(name: N, value: AddonConfig[N]) { config[name] = value; }
|
||||||
|
|
||||||
export function CVMat() { return getAddon().Mat; }
|
export function CVMat() { return getAddon().Mat; }
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { getAddon, getConfig } from "./addon";
|
export { getConfig as C } from "./addon";
|
||||||
import { Mat } from "./mat";
|
import { Mat } from "./mat";
|
||||||
|
|
||||||
export type TypedArray = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | BigUint64Array | BigInt64Array | Float32Array | Float64Array
|
export type TypedArray = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | BigUint64Array | BigInt64Array | Float32Array | Float64Array
|
||||||
|
|
||||||
export function FromCV(mat: any): Mat { return new (Mat as any)(mat); }
|
export function FromCV(mat: any): Mat { return new (Mat as any)(mat); }
|
||||||
export function M(mat: Mat) { return (mat as any).__mat__; }
|
export function M(mat: Mat) { return (mat as any).__mat__; }
|
||||||
export function C(name: Parameters<typeof getConfig>[0]) { return getConfig(name); }
|
|
||||||
|
|
||||||
export function resolveArgs<R extends Array<any>>(args: any[], checker: boolean | (() => boolean)): R {
|
export function resolveArgs<R extends Array<any>>(args: any[], checker: boolean | (() => boolean)): R {
|
||||||
if (typeof checker === "function") checker = checker();
|
if (typeof checker === "function") checker = checker();
|
||||||
|
77
src/cv/download.ts
Normal file
77
src/cv/download.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import os from "os";
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import { C } from "./common";
|
||||||
|
|
||||||
|
const URLS = {
|
||||||
|
GITHUB: `https://github.com/kangkang520/node-addons/releases/download/cv{{version}}/cv_{{platform}}_{{arch}}.node`,
|
||||||
|
URNAS: `http://git.urnas.cn:5200/yizhi-js-lib/opencv/releases/download/{{version}}/cv_{{platform}}_{{arch}}.node`,
|
||||||
|
}
|
||||||
|
|
||||||
|
function getURL(template: string) {
|
||||||
|
const version = require("../../package.json").version;
|
||||||
|
let platform = "";
|
||||||
|
let arch = "";
|
||||||
|
switch (os.platform()) {
|
||||||
|
case "win32":
|
||||||
|
platform = "windows";
|
||||||
|
break;
|
||||||
|
case "linux":
|
||||||
|
platform = "linux";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported platform: ${os.platform()}, Please compile the addon yourself.`);
|
||||||
|
}
|
||||||
|
switch (os.arch()) {
|
||||||
|
case "x64":
|
||||||
|
arch = "x64";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported architecture: ${os.arch()}, Please compile the addon yourself.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return template.replaceAll("{{version}}", version).replaceAll("{{platform}}", platform).replaceAll("{{arch}}", arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getStream() {
|
||||||
|
for (const [name, url] of Object.entries(URLS)) {
|
||||||
|
try {
|
||||||
|
return await fetch(getURL(url)).then(res => {
|
||||||
|
if (res.status != 200) throw new Error("Failed to download addon.");
|
||||||
|
return res.blob().then(b => b.stream());
|
||||||
|
})
|
||||||
|
} catch (e) { }
|
||||||
|
}
|
||||||
|
throw new Error("Failed to download addon.");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function downloadAddon(savename?: string) {
|
||||||
|
const defaultAddon = path.resolve(process.cwd(), C("ADDON_PATH"));
|
||||||
|
const saveName = savename ? path.resolve(path.dirname(defaultAddon), savename) : defaultAddon;
|
||||||
|
if (fs.existsSync(saveName)) return saveName;
|
||||||
|
|
||||||
|
await fs.promises.mkdir(path.dirname(saveName), { recursive: true });
|
||||||
|
|
||||||
|
const stream = await getStream();
|
||||||
|
const cacheFile = await new Promise<string>((resolve, reject) => {
|
||||||
|
const cacheFile = path.join(os.tmpdir(), Date.now() + ".cv.node");
|
||||||
|
let fsStream!: ReturnType<typeof fs.createWriteStream>;
|
||||||
|
stream.pipeTo(new WritableStream({
|
||||||
|
start(controller) {
|
||||||
|
fsStream = fs.createWriteStream(cacheFile);
|
||||||
|
},
|
||||||
|
async write(chunk, controller) {
|
||||||
|
await new Promise<void>((resolve, reject) => fsStream.write(chunk, err => err ? reject(err) : resolve()));
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
fsStream.end();
|
||||||
|
resolve(cacheFile);
|
||||||
|
},
|
||||||
|
abort() { }
|
||||||
|
})).catch(reject);
|
||||||
|
});
|
||||||
|
|
||||||
|
await fs.promises.cp(cacheFile, saveName);
|
||||||
|
await fs.promises.rm(cacheFile);
|
||||||
|
return saveName;
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
export { setConfig as config } from "./addon";
|
export { setConfig as config } from "./addon";
|
||||||
|
export { downloadAddon } from "./download";
|
||||||
export * from "./mat";
|
export * from "./mat";
|
||||||
export * from "./consts";
|
export * from "./consts";
|
||||||
export * from "./proc";
|
export * from "./proc";
|
||||||
|
@ -2,6 +2,7 @@ import cv from ".";
|
|||||||
|
|
||||||
|
|
||||||
async function test() {
|
async function test() {
|
||||||
|
await cv.downloadAddon();
|
||||||
const fs = await import("fs");
|
const fs = await import("fs");
|
||||||
// const buffer = fs.readFileSync("data/im1.jpeg")
|
// const buffer = fs.readFileSync("data/im1.jpeg")
|
||||||
const res = await cv.imread("test_data/im1.jpeg");
|
const res = await cv.imread("test_data/im1.jpeg");
|
||||||
|
@ -105,9 +105,6 @@ async function downloadFromURL(name, url, resolver) {
|
|||||||
|
|
||||||
if (!checkFile(saveName)) {
|
if (!checkFile(saveName)) {
|
||||||
console.log(`开始下载${name}, 地址:${url}`);
|
console.log(`开始下载${name}, 地址:${url}`);
|
||||||
await fetch(url).then(res => {
|
|
||||||
console.log(res.status)
|
|
||||||
})
|
|
||||||
const result = spawnSync("curl", ["-o", saveName + ".cache", "-L", url, "-s", "-w", "%{http_code}"], { ...spawnOption, stdio: "pipe" });
|
const result = spawnSync("curl", ["-o", saveName + ".cache", "-L", url, "-s", "-w", "%{http_code}"], { ...spawnOption, stdio: "pipe" });
|
||||||
assert(result.status == 0 && result.stdout.toString() == "200", `下载${name}失败`);
|
assert(result.status == 0 && result.stdout.toString() == "200", `下载${name}失败`);
|
||||||
fs.renameSync(saveName + ".cache", saveName);
|
fs.renameSync(saveName + ".cache", saveName);
|
||||||
|
Reference in New Issue
Block a user