2019-09-04 14:37:02 -04:00
/**
2019-09-13 14:34:08 +01:00
* @author n1474335 [n1474335@gmail.com]
2019-09-04 14:37:02 -04:00
* @author mshwed [m@ttshwed.com]
2020-03-27 13:12:08 +00:00
* @author Matt C [me@mitt.dev]
2019-09-04 14:37:02 -04:00
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/
2022-09-09 14:45:06 -07:00
import Operation from "../Operation.mjs" ;
import OperationError from "../errors/OperationError.mjs" ;
import { isImage } from "../lib/FileType.mjs" ;
import { toBase64 } from "../lib/Base64.mjs" ;
import { isWorkerEnvironment } from "../Utils.mjs" ;
import { createWorker } from "tesseract.js" ;
2024-06-21 14:12:28 +01:00
const OEM_MODES = [ "Tesseract only" , "LSTM only" , "Tesseract/LSTM Combined" ];
2022-09-09 14:45:06 -07:00
/**
* Optical Character Recognition operation
*/
class OpticalCharacterRecognition extends Operation {
/**
* OpticalCharacterRecognition constructor
*/
constructor () {
super ();
this . name = "Optical Character Recognition" ;
this . module = "OCR" ;
this . description = "Optical character recognition or optical character reader (OCR) is the mechanical or electronic conversion of images of typed, handwritten or printed text into machine-encoded text.<br><br>Supported image formats: png, jpg, bmp, pbm." ;
this . infoURL = "https://wikipedia.org/wiki/Optical_character_recognition" ;
this . inputType = "ArrayBuffer" ;
this . outputType = "string" ;
this . args = [
{
name : "Show confidence" ,
type : "boolean" ,
value : true
2024-06-21 14:12:28 +01:00
},
{
name : "OCR Engine Mode" ,
type : "option" ,
value : OEM_MODES ,
defaultIndex : 1
2022-09-09 14:45:06 -07:00
}
];
}
/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {string}
*/
async run ( input , args ) {
2024-06-21 14:12:28 +01:00
const [ showConfidence , oemChoice ] = args ;
2022-09-09 14:45:06 -07:00
if ( ! isWorkerEnvironment ()) throw new OperationError ( "This operation only works in a browser" );
const type = isImage ( input );
if ( ! type ) {
2022-09-16 14:15:54 +01:00
throw new OperationError ( "Unsupported file type (supported: jpg,png,pbm,bmp) or no file provided" );
2022-09-09 14:45:06 -07:00
}
2024-06-21 14:12:28 +01:00
const assetDir = ` ${ self . docURL } /assets/` ;
const oem = OEM_MODES . indexOf ( oemChoice );
2022-09-16 14:15:54 +01:00
2022-09-09 14:45:06 -07:00
try {
self . sendStatusMessage ( "Spinning up Tesseract worker..." );
const image = `data: ${ type } ;base64, ${ toBase64 ( input ) } ` ;
2024-06-21 14:12:28 +01:00
const worker = await createWorker ( "eng" , oem , {
2022-09-16 14:15:54 +01:00
workerPath : ` ${ assetDir } tesseract/worker.min.js` ,
langPath : ` ${ assetDir } tesseract/lang-data` ,
corePath : ` ${ assetDir } tesseract/tesseract-core.wasm.js` ,
2022-09-09 14:45:06 -07:00
logger : progress => {
if ( isWorkerEnvironment ()) {
self . sendStatusMessage ( `Status: ${ progress . status }${ progress . status === "recognizing text" ? ` - ${ ( parseFloat ( progress . progress ) * 100 ). toFixed ( 2 ) } %` : "" } ` );
}
}
});
self . sendStatusMessage ( "Finding text..." );
const result = await worker . recognize ( image );
if ( showConfidence ) {
return `Confidence: ${ result . data . confidence } %\n\n ${ result . data . text } ` ;
} else {
return result . data . text ;
}
} catch ( err ) {
throw new OperationError ( `Error performing OCR on image. ( ${ err } )` );
}
}
}
export default OpticalCharacterRecognition ;