從 0 開始製作一個 NodeJS 命令列驗證碼識別工具。實現如下效果。
初始化專案
# 建立 recognition 專案mkdir recognitioncd recognitionnpm 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# 登入到 npmnpm adduser# 發包npm publish --access public# 全域性安裝npm install -g @chenng/recognition複製程式碼