|
|
|
@ -1,138 +1,93 @@
@@ -1,138 +1,93 @@
|
|
|
|
|
const readImage = require('tesseract.js-core/src/utils/readImage'); |
|
|
|
|
var latestJob, |
|
|
|
|
Module, |
|
|
|
|
base, |
|
|
|
|
adapter = {}, |
|
|
|
|
dump = require('./dump.js'), |
|
|
|
|
desaturate = require('./desaturate.js'); |
|
|
|
|
|
|
|
|
|
function dispatchHandlers(packet, send){ |
|
|
|
|
function respond(status, data){ |
|
|
|
|
send({ |
|
|
|
|
jobId: packet.jobId, |
|
|
|
|
status, |
|
|
|
|
action: packet.action, |
|
|
|
|
data |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
respond.resolve = respond.bind(this, 'resolve'); |
|
|
|
|
respond.reject = respond.bind(this, 'reject'); |
|
|
|
|
respond.progress = respond.bind(this, 'progress'); |
|
|
|
|
|
|
|
|
|
latestJob = respond; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
if(packet.action === 'recognize'){ |
|
|
|
|
handleRecognize(packet.payload, respond); |
|
|
|
|
} else if (packet.action === 'detect'){ |
|
|
|
|
handleDetect(packet.payload, respond); |
|
|
|
|
} |
|
|
|
|
} catch (err) { |
|
|
|
|
// Prepare exception to travel through postMessage
|
|
|
|
|
err = err.toString(); |
|
|
|
|
const { readImage, loadLang } = require('tesseract.js-utils'); |
|
|
|
|
const dump = require('./dump'); |
|
|
|
|
|
|
|
|
|
respond.reject(err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
exports.dispatchHandlers = dispatchHandlers; |
|
|
|
|
let Module; |
|
|
|
|
let base; |
|
|
|
|
let latestJob; |
|
|
|
|
let adapter = {}; |
|
|
|
|
|
|
|
|
|
exports.setAdapter = function setAdapter(impl){ |
|
|
|
|
adapter = impl; |
|
|
|
|
}; |
|
|
|
|
const handleInit = (req, res) => { |
|
|
|
|
let MIN_MEMORY = 100663296; |
|
|
|
|
|
|
|
|
|
if (['chi_sim', 'chi_tra', 'jpn'].includes(req.options.lang)) { |
|
|
|
|
MIN_MEMORY = 167772160; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function handleInit(req, res){ |
|
|
|
|
var MIN_MEMORY = 100663296; |
|
|
|
|
if (!Module || Module.TOTAL_MEMORY < MIN_MEMORY) { |
|
|
|
|
const Core = adapter.getCore(req, res); |
|
|
|
|
|
|
|
|
|
if(['chi_sim', 'chi_tra', 'jpn'].includes(req.options.lang)){ |
|
|
|
|
MIN_MEMORY = 167772160; |
|
|
|
|
} |
|
|
|
|
res.progress({ status: 'initializing tesseract', progress: 0 }); |
|
|
|
|
|
|
|
|
|
if(!Module || Module.TOTAL_MEMORY < MIN_MEMORY){ |
|
|
|
|
var Core = adapter.getCore(req, res); |
|
|
|
|
|
|
|
|
|
res.progress({ status: 'initializing tesseract', progress: 0 }) |
|
|
|
|
|
|
|
|
|
return Core({ |
|
|
|
|
// TOTAL_MEMORY: MIN_MEMORY,
|
|
|
|
|
TesseractProgress(percent){ |
|
|
|
|
latestJob.progress({ status: 'recognizing text', progress: Math.max(0, (percent-30)/70) }); |
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
|
.then((TessModule) => { |
|
|
|
|
Module = TessModule; |
|
|
|
|
base = new Module.TessBaseAPI(); |
|
|
|
|
res.progress({ status: 'initializing tesseract', progress: 1 }); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
return Core({ |
|
|
|
|
// TOTAL_MEMORY: MIN_MEMORY,
|
|
|
|
|
TesseractProgress(percent) { |
|
|
|
|
latestJob.progress({ status: 'recognizing text', progress: Math.max(0, (percent - 30) / 70) }); |
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
|
.then((TessModule) => { |
|
|
|
|
Module = TessModule; |
|
|
|
|
base = new Module.TessBaseAPI(); |
|
|
|
|
res.progress({ status: 'initialized tesseract', progress: 1 }); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return new Promise(); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
function setImage(Module, base, image) { |
|
|
|
|
const setImage = (image) => { |
|
|
|
|
const { w, h, data } = readImage(Module, Array.from(image)); |
|
|
|
|
|
|
|
|
|
base.SetImage(data); |
|
|
|
|
base.SetRectangle(0, 0, w, h); |
|
|
|
|
return data; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function loadLanguage(req, res, cb){ |
|
|
|
|
var lang = req.options.lang, |
|
|
|
|
langFile = lang + '.traineddata'; |
|
|
|
|
|
|
|
|
|
if(!Module._loadedLanguages) Module._loadedLanguages = {}; |
|
|
|
|
if(lang in Module._loadedLanguages) return cb(); |
|
|
|
|
|
|
|
|
|
adapter.getLanguageData(req, res, function(data){ |
|
|
|
|
res.progress({ status: 'loading ' + langFile, progress: 0 }); |
|
|
|
|
Module.FS.writeFile(langFile, data); |
|
|
|
|
Module._loadedLanguages[lang] = true; |
|
|
|
|
res.progress({ status: 'loading ' + langFile, progress: 1 }); |
|
|
|
|
cb(); |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const loadLanguage = (req, res, cb) => { |
|
|
|
|
const { options: { lang }, workerOptions: { langPath } } = req; |
|
|
|
|
return loadLang({ |
|
|
|
|
langs: lang, |
|
|
|
|
tessModule: Module, |
|
|
|
|
langURI: langPath, |
|
|
|
|
cache: true, |
|
|
|
|
}).then(cb); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
function handleRecognize(req, res){ |
|
|
|
|
const handleRecognize = (req, res) => { |
|
|
|
|
handleInit(req, res) |
|
|
|
|
.then(() => { |
|
|
|
|
loadLanguage(req, res, () => { |
|
|
|
|
var options = req.options; |
|
|
|
|
const { options } = req; |
|
|
|
|
|
|
|
|
|
function progressUpdate(progress){ |
|
|
|
|
res.progress({ status: 'initializing api', progress: progress }); |
|
|
|
|
} |
|
|
|
|
const progressUpdate = (progress) => { |
|
|
|
|
res.progress({ status: 'initializing api', progress }); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
progressUpdate(0); |
|
|
|
|
base.Init(null, req.options.lang); |
|
|
|
|
progressUpdate(.3); |
|
|
|
|
base.Init(null, options.lang); |
|
|
|
|
progressUpdate(0.3); |
|
|
|
|
|
|
|
|
|
for (var option in options) { |
|
|
|
|
if (options.hasOwnProperty(option)) { |
|
|
|
|
base.SetVariable(option, options[option]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Object.keys(options).forEach((key) => { |
|
|
|
|
base.SetVariable(key, options[key]); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
progressUpdate(.6); |
|
|
|
|
var ptr = setImage(Module, base, req.image); |
|
|
|
|
progressUpdate(0.6); |
|
|
|
|
const ptr = setImage(req.image); |
|
|
|
|
progressUpdate(1); |
|
|
|
|
|
|
|
|
|
base.Recognize(null); |
|
|
|
|
|
|
|
|
|
var result = dump(Module, base); |
|
|
|
|
const result = dump(Module, base); |
|
|
|
|
|
|
|
|
|
base.End(); |
|
|
|
|
Module._free(ptr); |
|
|
|
|
|
|
|
|
|
res.resolve(result); |
|
|
|
|
}) |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function handleDetect(req, res){ |
|
|
|
|
const handleDetect = (req, res) => { |
|
|
|
|
handleInit(req, res) |
|
|
|
|
.then(() => { |
|
|
|
|
req.options.lang = 'osd'; |
|
|
|
@ -140,17 +95,17 @@ function handleDetect(req, res){
@@ -140,17 +95,17 @@ function handleDetect(req, res){
|
|
|
|
|
base.Init(null, 'osd'); |
|
|
|
|
base.SetPageSegMode(Module.PSM_OSD_ONLY); |
|
|
|
|
|
|
|
|
|
var ptr = setImage(Module, base, req.image), |
|
|
|
|
results = new Module.OSResults(); |
|
|
|
|
const ptr = setImage(req.image); |
|
|
|
|
const results = new Module.OSResults(); |
|
|
|
|
|
|
|
|
|
if(!base.DetectOS(results)){ |
|
|
|
|
if (!base.DetectOS(results)) { |
|
|
|
|
base.End(); |
|
|
|
|
Module._free(ptr); |
|
|
|
|
res.reject("Failed to detect OS"); |
|
|
|
|
res.reject('Failed to detect OS'); |
|
|
|
|
} else { |
|
|
|
|
var best = results.get_best_result(), |
|
|
|
|
oid = best.get_orientation_id(), |
|
|
|
|
sid = best.get_script_id(); |
|
|
|
|
const best = results.get_best_result(); |
|
|
|
|
const oid = best.get_orientation_id(); |
|
|
|
|
const sid = best.get_script_id(); |
|
|
|
|
|
|
|
|
|
base.End(); |
|
|
|
|
Module._free(ptr); |
|
|
|
@ -160,9 +115,40 @@ function handleDetect(req, res){
@@ -160,9 +115,40 @@ function handleDetect(req, res){
|
|
|
|
|
script: results.get_unicharset().get_script_from_script_id(sid), |
|
|
|
|
script_confidence: best.get_sconfidence(), |
|
|
|
|
orientation_degrees: [0, 270, 180, 90][oid], |
|
|
|
|
orientation_confidence: best.get_oconfidence() |
|
|
|
|
orientation_confidence: best.get_oconfidence(), |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
exports.dispatchHandlers = (packet, send) => { |
|
|
|
|
const respond = (status, data) => { |
|
|
|
|
send({ |
|
|
|
|
jobId: packet.jobId, |
|
|
|
|
status, |
|
|
|
|
action: packet.action, |
|
|
|
|
data, |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
respond.resolve = respond.bind(this, 'resolve'); |
|
|
|
|
respond.reject = respond.bind(this, 'reject'); |
|
|
|
|
respond.progress = respond.bind(this, 'progress'); |
|
|
|
|
|
|
|
|
|
latestJob = respond; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
if (packet.action === 'recognize') { |
|
|
|
|
handleRecognize(packet.payload, respond); |
|
|
|
|
} else if (packet.action === 'detect') { |
|
|
|
|
handleDetect(packet.payload, respond); |
|
|
|
|
} |
|
|
|
|
} catch (err) { |
|
|
|
|
// Prepare exception to travel through postMessage
|
|
|
|
|
respond.reject(err.toString()); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
exports.setAdapter = (impl) => { |
|
|
|
|
adapter = impl; |
|
|
|
|
}; |
|
|
|
|