從 0 開始製作一個 NodeJS 命令列驗證碼識別工具。實現如下效果。
初始化專案
# 建立 recognition 專案
mkdir recognition
cd recognition
npm init -y
# 安裝主依賴
yarn add images tesseract.js
# 安裝工具依賴
yarn add chalk yargs
# 可選依賴
yarn add socks5-http-client
複製程式碼
依賴說明
-
images:Node.js 輕量級跨平臺影象編碼庫,用於處理下載下來的圖片
-
tesseract.js:純 JS 實現的 OCR(光學字元識別)工具,用於影象內容識別
-
chalk:讓命令列內容樣式好看
-
yargs:命令列引數解析器
-
socks5-http-client:SOCKS v5,用於設定代理,在需要拉取某些不能直接訪問的資源時使用,request proxy 例子
專案準備
新建 cli.js
通常命令列工具入口名字為 cli.js
,我們新建一個 cli.js
檔案,並在開頭寫上:
#!/usr/bin/env node
複製程式碼
這樣,我們告訴 *nix 系統,JavaScript 檔案的直譯器應該是 /usr/bin/env node
,它查詢本地安裝的 node
。
配置 bin
// package.json
{
"bin": {
"reg": "./cli.js"
}
}
複製程式碼
這樣配置完成後,別人 npm install -g @chenng/recognition
的包,就可以直接通過命令列執行了:
reg --url=https://static.chenng.cn/imgs/test_img.png
複製程式碼
link 本地開發
我們如何能夠在本地可以使用 rec
命令呢?只需要把本專案 link 即可:
yarn link
複製程式碼
核心邏輯
主要邏輯在 cli.js
和 recognize.js
中。這裡有幾個注意點:
- request 圖片的時候要設定
encoding: null
,否則返回的是亂碼 - 初次使用的時候需要下載訓練集,需要花點時間
const Tesseract = require('tesseract.js');
const images = require('images');
const requset = require('request');
const fs = require('fs');
const { promisify } = require('util');
const chalk = require('chalk');
const writeFile = promisify(fs.writeFile);
const rp = promisify(requset);
class Recognize {
constructor(url) {
Recognize.downloadDir = `${__dirname}/dist/`;
Recognize.downloadFile = `${__dirname}/dist/temp.png`;
this.url = url;
this.start();
}
async start() {
const data = await this.downloadImg();
await writeFile(Recognize.downloadFile, data);
this.recognize();
const result = await Tesseract.recognize(Recognize.downloadFile, {
lang: 'eng',
tessedit_char_blacklist: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
});
console.log(`
識別成功!
識別結果為:${chalk.green(result.text)}
`);
}
async downloadImg() {
if (!fs.existsSync(Recognize.downloadDir)) {
fs.mkdirSync(Recognize.downloadDir);
console.log(`建立了 ${Recognize.downloadDir} 資料夾`);
}
const res = await rp({
url: this.url,
method: 'GET',
encoding: null,
});
return res.body;
}
recognize() {
// 放大圖片,並覆蓋原始檔
images(Recognize.downloadFile)
.size(400)
.save(Recognize.downloadFile);
}
}
module.exports = Recognize;
複製程式碼
具體可以檢視原始碼倉庫:github.com/ringcrl/rec…
釋出上線
# 新建程式碼倉庫,git push
# 登入到 npm
npm adduser
# 發包
npm publish --access public
# 全域性安裝
npm install -g @chenng/recognition
複製程式碼