本文一步一步教你如何在小程序中使用最新版的OpenCV(本文发布时为4.5.5)
重要提示:开发者工具不要勾选编译为ES5
安装基础工具
pacman -S base-devel cmake git
git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install 2.0.10
./emsdk activate 2.0.10
source ./emsdk_env.sh
进入 https://opencv.org/releases/ 页面下载opencv最新版源码,并解压缩,并进入解压缩后文件夹
修改platforms/js/opencv_js.config.py
文件根据情况,去掉不用的模块
# white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d, photo, aruco, calib3d])
white_list = makeWhiteList([core, imgproc])
默认OpenCV4会将wasm以base64存到js文件,输出单独wasm文件便于用于微信小程序
打开modules/js/CMakeLists.txt
,去掉 SINGLE_FILE
参数
# set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1 -s SINGLE_FILE=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1")
微信小程序不支持eval()
和new Function()
等动态执行函数,在modules/js/CMakeLists.txt
中,增加DYNAMIC_EXECUTION
的编译参数屏蔽这些函数的输出
# set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1 -s SINGLE_FILE=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s DYNAMIC_EXECUTION=0")
emcmake python ./platforms/js/build_js.py -h
emcmake python ./platforms/js/build_js.py build_wasm --build_wasm --build_test
build_wasm\bin
目录生成了opencv.js,opencv_js.wasm,tests.html文件
brotli -o build_wasm/bin/opencv_js.wasm.br build_wasm/bin/opencv_js.wasm
npm i -g http-server
http-server build_wasm/bin/
在浏览器打开 http://127.0.0.1:8080/tests.html
可以查看测试结果
修改前先将opencv.js
格式化一下,微信小程序不支持通过url获取wasm,修改下instantiateAsync方法的else分支里面的代码,让读小程序项目下的opencv_js.wasm文件
function instantiateAsync() {
if (
!wasmBinary &&
typeof WebAssembly.instantiateStreaming === "function" &&
!isDataURI(wasmBinaryFile) &&
!isFileURI(wasmBinaryFile) &&
typeof fetch === "function"
) {
return fetch(wasmBinaryFile, { credentials: "same-origin" }).then(
function (response) {
var result = WebAssembly.instantiateStreaming(response, info);
return result.then(
receiveInstantiatedSource,
function (reason) {
err("wasm streaming compile failed: " + reason);
err("falling back to ArrayBuffer instantiation");
return instantiateArrayBuffer(receiveInstantiatedSource);
}
);
}
);
} else {
// return instantiateArrayBuffer(receiveInstantiatedSource);
var result = WebAssembly.instantiate("/opencv/opencv_js.wasm.br", info);
return result.then(
receiveInstantiatedSource,
function (reason) {
err("wasm streaming compile failed: " + reason);
err("falling back to ArrayBuffer instantiation");
return instantiateArrayBuffer(receiveInstantiatedSource);
}
);
}
}
没有performance.now方法
_emscripten_get_now = function () {
// return performance.now();
return Date.now()
};
这些方法定义在modules\js\src\helpers.js
文件中,修改后重新编译和生成wasm文件即可
参考示例