ElectronOCR:基于Electron+React+Tesseract的MACOS下的OCR工具

Github Repo 地址
文章地址
MAXOS Darwin x64下载javascript

笔者一直在MacOS上没找到太顺心的OCR工具,致使看书的时候不少东西只能手打,略烦。正好前段时间用了Tesseract,就用Electron封装了一个,这里简要记述下开发当中的一些坑和要点,往后有空把Electron整理好也出个系列html

Introduction

这东西,大概是这个样子:
java

如今本机上安装个Tesseract:node

brew install imagemagick
brew install tesseract --all-languages

而后直接下载打开便可。webpack

Development

Setup

  • use npm install or npm link to install dependencesgit

  • use npm install -g electron-prebuilt to enable the global electrongithub

Develop & Hot-Reloading

  • use npm start to start webpak hot-middle serverweb

  • use npm run electron-test to use electron and set env to developmentnpm

Package

  • use npm run buildto generate list file for web modules编程

  • usenpm run package-osx to build and package into dmg

Web部分

笔者Web部分仍是采用Webpack+React+Redux(待加入),关于这部分的单独代码能够借鉴个人Webpack套装以及Webpack-React-Redux-Boilerplate这个示范Boilerplate。须要注意的是,在Electron 1.x以后API和0.x系列有了较大的变化,不少Github上的项目在升级到1.2.0以后不可用。

支持Hot Reload的环境搭建

Electron其实是一个封装好的近似浏览器,所以Hot Reload与纯粹的Web开发区别不大,都是先起一个Hot Load Server,监听3000端口。不过须要作修改的是,在Electron中全部的脚本都要从localhost:3000加载,主要修改有:

var devEntry = [
    'eventsource-polyfill',
    //修改WHM的默认加载地址
    `webpack-hot-middleware/client?path=http://localhost:${port}/__webpack_hmr`,
];
//修改默认的公共路径前缀
config.output.publicPath = `http://localhost:${port}/dist/`//公共目录名

在dev.html中也须要修改下加载的脚本的地址:

<html>
<head>
    <title>Index For Debug</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
<div id="root"></div>
</body>
</html>
<script src="http://localhost:3000/dist/vendors.bundle.js"></script>
<script src="http://localhost:3000/dist/main.bundle.js"></script>

在渲染进程中引入本地模块

const {dialog} = window.require('electron').remote;
const fs = window.require("fs");

首先为了不Webpack在打包时报错electron不存在,建议是将全部Node或者Electron提供的模块用window.require方式,这样Webpack会忽略引入。

Native部分

建立本地窗口

/**
 * Created by apple on 16/6/3.
 */
const electron = require('electron');
// 用于控制应用生命周期
const {app} = electron;
// 用于建立本地窗口
const {BrowserWindow} = electron;

//为Window对象建立一个全局的引用,不然可能被JavaScript的垃圾回收机制自动回收
let win;

/**
 * @function 建立窗口
 */
function createWindow() {
    // 建立相似于浏览器的窗口
    win = new BrowserWindow({width: 800, height: 600});

    // 加载应用入口文件,本文件为测试文件,所以加载的是测试
    win.loadURL(`file://${__dirname}/dist/app.html`);

    // 启动调试工具,若是是开发环境下则不须要开启
    // win.webContents.openDevTools();

    // 设置窗口关闭事件
    win.on('closed', () => {
        //由于上面是设置了一个全局引用,所以这里须要对该对象解除引用
        //若是你的应用支持打开多窗口,能够把全部的引用存入一个数组中,而后在这里动态删除
        win = null;
    });
}

// 在基本环境准备好以后的回调
app.on('ready', createWindow);

// 全部窗口都关闭以后的回调
app.on('window-all-closed', () => {
    //在OSX中常常是用户虽然关闭了主窗口,可是仍然但愿使用Menu Bar,所以这里不进行强行关闭
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

// 应用被从新激活以后的回调
app.on('activate', () => {
    // 在Dock中的Menu Bar被点击以后从新激活应用
    if (win === null) {
        createWindow();
    }
});

打包

通常来讲,Electron推荐的打包方式有三种,这里笔者使用的是electron-packager这个便捷工具,不过碰到一个蛋疼的问题是Electron一直下载不下来,挂了SS加上proxychains4都不行。所以最终仍是用编程方式进行打包:

require('babel-polyfill');
const exec = require('child_process').exec;

const argv = require('minimist')(process.argv.slice(2));

const platform = argv._[0];//编译的目标平台

const packager = require('electron-packager');

console.log("Current NODE_ENV = " + process.env.NODE_ENV);//判断编译时环境

const arch = "x64";

packager({
    dir: "./",
    platform,
    arch,
    out: `release/`,
    override: true,
    prune: true,
    download: {
        mirror: "https://npm.taobao.org/mirrors/electron/" //设定Electron的下载地址
    }
}, function done_callback(err, appPaths) { /* … */
});

而后将脚本封装到package.json中:

"package-osx": "npm run clean-electron && NODE_ENV=production node -r babel-register package.js darwin",

避免打包node_modules

在Web开发中咱们会将譬如React、Redux等等依赖项加入到package.json的dependencies中,不过Electron Packager会将node_modules也打包到应用中。而后代码都已经经过Webpack打包编译到统一的js脚本中,所以首先能够设置prune为true,这样能够避免打包全部的dev-dependencies。一样,咱们也须要将非本地模块所有放到dev-dependencies中。

相关文章
相关标签/搜索