Browse Source

Added OutputFormats option/interface for setting output

dev/v4
Balearica 2 years ago
parent
commit
c407aeb559
  1. 1
      examples/browser/basic.html
  2. 2
      examples/browser/download-pdf.html
  3. 4
      examples/browser/image-processing.html
  4. 2
      examples/node/download-pdf.js
  5. 26
      examples/node/scheduler.js
  6. 2
      src/constants/imageType.js
  7. 13
      src/createWorker.js
  8. 28
      src/index.d.ts
  9. 36
      src/utils/circularize.js
  10. 17
      src/worker-script/constants/defaultOutput.js
  11. 135
      src/worker-script/index.js
  12. 274
      src/worker-script/utils/dump.js

1
examples/browser/basic.html

@ -8,6 +8,7 @@
const recognize = async ({ target: { files } }) => { const recognize = async ({ target: { files } }) => {
const { data: { text } } = await Tesseract.recognize(files[0], 'eng', { const { data: { text } } = await Tesseract.recognize(files[0], 'eng', {
corePath: '../../node_modules/tesseract.js-core/tesseract-core.wasm.js', corePath: '../../node_modules/tesseract.js-core/tesseract-core.wasm.js',
workerPath: "/dist/worker.dev.js",
logger: m => console.log(m), logger: m => console.log(m),
}); });
console.log(text); console.log(text);

2
examples/browser/download-pdf.html

@ -21,7 +21,7 @@
const recognize = async ({ target: { files } }) => { const recognize = async ({ target: { files } }) => {
await worker.loadLanguage('eng'); await worker.loadLanguage('eng');
await worker.initialize('eng'); await worker.initialize('eng');
const res = await worker.recognize(files[0], {savePDF: true}); const res = await worker.recognize(files[0],{pdfTitle: "Example PDF"},{pdf: true});
pdf = res.data.pdf; pdf = res.data.pdf;
const text = res.data.text; const text = res.data.text;
const board = document.getElementById('board'); const board = document.getElementById('board');

4
examples/browser/image-processing.html

@ -45,8 +45,8 @@
await worker.initialize('eng'); await worker.initialize('eng');
await worker.initialize(); await worker.initialize();
const ret = await worker.recognize(files[0], { saveImageOriginal: true, saveImageGrey: true, saveImageBinary: true, rotateAuto: true }) const ret = await worker.recognize(files[0], {rotateAuto: true}, {imageColor: true, imageGrey: true, imageBinary: true});
document.getElementById("imgOriginal").src = ret.data.imageOriginal; document.getElementById("imgOriginal").src = ret.data.imageColor;
document.getElementById("imgGrey").src = ret.data.imageGrey; document.getElementById("imgGrey").src = ret.data.imageGrey;
document.getElementById("imgBinary").src = ret.data.imageBinary; document.getElementById("imgBinary").src = ret.data.imageBinary;

2
examples/node/download-pdf.js

@ -12,7 +12,7 @@ console.log(`Recognizing ${image}`);
const worker = await createWorker(); const worker = await createWorker();
await worker.loadLanguage('eng'); await worker.loadLanguage('eng');
await worker.initialize('eng'); await worker.initialize('eng');
const { data: { text, pdf } } = await worker.recognize(image, {savePDF: true}); const { data: { text, pdf } } = await worker.recognize(image, {pdfTitle: "Example PDF"}, {pdf: true});
console.log(text); console.log(text);
fs.writeFileSync('tesseract-ocr-result.pdf', Buffer.from(pdf)); fs.writeFileSync('tesseract-ocr-result.pdf', Buffer.from(pdf));
console.log('Generate PDF: tesseract-ocr-result.pdf'); console.log('Generate PDF: tesseract-ocr-result.pdf');

26
examples/node/scheduler.js

@ -0,0 +1,26 @@
const { createWorker, createScheduler } = require('../../');
const scheduler = createScheduler();
// Creates worker and adds to scheduler
const workerGen = async () => {
const worker = createWorker({cachePath: "."});
await worker.load();
await worker.loadLanguage('eng');
await worker.initialize('eng');
scheduler.addWorker(worker);
}
const workerN = 4;
(async () => {
const resArr = Array(workerN);
for (let i=0; i<workerN; i++) {
resArr[i] = workerGen();
}
await Promise.all(resArr);
/** Add 4 recognition jobs */
const results = await Promise.all(Array(10).fill(0).map(() => (
scheduler.addJob('recognize', 'https://tesseract.projectnaptha.com/img/eng_bw.png').then((x) => console.log(x.data.text))
)))
await scheduler.terminate(); // It also terminates all workers.
})();

2
src/constants/imageType.js

@ -1,5 +1,5 @@
module.exports = { module.exports = {
ORIGINAL: 0, COLOR: 0,
GREY: 1, GREY: 1,
BINARY: 2, BINARY: 2,
}; };

13
src/createWorker.js

@ -129,19 +129,11 @@ module.exports = async (_options = {}) => {
})) }))
); );
const recognize = async (image, opts = {}, jobId) => ( const recognize = async (image, opts = {}, output = {blocks: true, text: true, hocr: true, tsv: true}, jobId) => (
startJob(createJob({ startJob(createJob({
id: jobId, id: jobId,
action: 'recognize', action: 'recognize',
payload: { image: await loadImage(image), options: opts }, payload: { image: await loadImage(image), options: opts, output },
}))
);
const threshold = async (image, opts = {}, jobId) => (
startJob(createJob({
id: jobId,
action: 'threshold',
payload: { image: await loadImage(image), options: opts },
})) }))
); );
@ -215,7 +207,6 @@ module.exports = async (_options = {}) => {
initialize, initialize,
setParameters, setParameters,
recognize, recognize,
threshold,
getPDF, getPDF,
detect, detect,
terminate, terminate,

28
src/index.d.ts vendored

@ -23,8 +23,7 @@ declare namespace Tesseract {
initialize(langs?: string, oem?: OEM, jobId?: string): Promise<ConfigResult> initialize(langs?: string, oem?: OEM, jobId?: string): Promise<ConfigResult>
setParameters(params: Partial<WorkerParams>, jobId?: string): Promise<ConfigResult> setParameters(params: Partial<WorkerParams>, jobId?: string): Promise<ConfigResult>
getImage(type: imageType): string getImage(type: imageType): string
recognize(image: ImageLike, options?: Partial<RecognizeOptions>, jobId?: string): Promise<RecognizeResult> recognize(image: ImageLike, options?: Partial<RecognizeOptions>, output?: Partial<OutputFormats>, jobId?: string): Promise<RecognizeResult>
threshold(image: ImageLike, options?: Partial<RecognizeOptions>, jobId?: string): Promise<RecognizeResult>
detect(image: ImageLike, jobId?: string): Promise<DetectResult> detect(image: ImageLike, jobId?: string): Promise<DetectResult>
terminate(jobId?: string): Promise<ConfigResult> terminate(jobId?: string): Promise<ConfigResult>
getPDF(title?: string, textonly?: boolean, jobId?: string):Promise<GetPDFResult> getPDF(title?: string, textonly?: boolean, jobId?: string):Promise<GetPDFResult>
@ -54,16 +53,25 @@ declare namespace Tesseract {
tessjs_create_unlv: string tessjs_create_unlv: string
tessjs_create_osd: string tessjs_create_osd: string
} }
interface OutputFormats {
text: boolean;
blocks: boolean;
hocr: boolean;
tsv: boolean;
box: boolean;
unlv: boolean;
osd: boolean;
pdf: boolean;
imageColor: boolean;
imageGrey: boolean;
imageBinary: boolean;
}
interface RecognizeOptions { interface RecognizeOptions {
rectangle: Rectangle rectangle: Rectangle
saveImageOriginal: boolean
saveImageGrey: boolean
saveImageBinary: boolean
savePDF: boolean
pdfTitle: string pdfTitle: string
pdfTextOnly: boolean pdfTextOnly: boolean
rotateAuto: boolean rotateAuto: boolean
rotateRadians: float rotateRadians: number
} }
interface ConfigResult { interface ConfigResult {
jobId: string jobId: string
@ -117,7 +125,7 @@ declare namespace Tesseract {
RAW_LINE = '13' RAW_LINE = '13'
} }
const enum imageType { const enum imageType {
ORIGINAL = 0, COLOR = 0,
GREY = 1, GREY = 1,
BINARY = 2 BINARY = 2
} }
@ -218,7 +226,7 @@ declare namespace Tesseract {
page: Page; page: Page;
} }
interface Page { interface Page {
blocks: Block[]; blocks: Block[] | null;
confidence: number; confidence: number;
lines: Line[]; lines: Line[];
oem: string; oem: string;
@ -234,7 +242,7 @@ declare namespace Tesseract {
box: string | null; box: string | null;
unlv: string | null; unlv: string | null;
sd: string | null; sd: string | null;
imageOriginal: string | null; imageColor: string | null;
imageGrey: string | null; imageGrey: string | null;
imageBinary: string | null; imageBinary: string | null;
rotateRadians: number | null; rotateRadians: number | null;

36
src/utils/circularize.js

@ -22,31 +22,33 @@ module.exports = (page) => {
const words = []; const words = [];
const symbols = []; const symbols = [];
page.blocks.forEach((block) => { if (page.blocks) {
block.paragraphs.forEach((paragraph) => { page.blocks.forEach((block) => {
paragraph.lines.forEach((line) => { block.paragraphs.forEach((paragraph) => {
line.words.forEach((word) => { paragraph.lines.forEach((line) => {
word.symbols.forEach((sym) => { line.words.forEach((word) => {
symbols.push({ word.symbols.forEach((sym) => {
...sym, page, block, paragraph, line, word, symbols.push({
...sym, page, block, paragraph, line, word,
});
});
words.push({
...word, page, block, paragraph, line,
}); });
}); });
words.push({ lines.push({
...word, page, block, paragraph, line, ...line, page, block, paragraph,
}); });
}); });
lines.push({ paragraphs.push({
...line, page, block, paragraph, ...paragraph, page, block,
}); });
}); });
paragraphs.push({ blocks.push({
...paragraph, page, block, ...block, page,
}); });
}); });
blocks.push({ }
...block, page,
});
});
return { return {
...page, blocks, paragraphs, lines, words, symbols, ...page, blocks, paragraphs, lines, words, symbols,

17
src/worker-script/constants/defaultOutput.js

@ -0,0 +1,17 @@
/*
* default output formats for tesseract.js
*/
module.exports = {
text: true,
blocks: true,
hocr: true,
tsv: true,
box: false,
unlv: false,
osd: false,
pdf: false,
imageColor: false,
imageGrey: false,
imageBinary: false
};

135
src/worker-script/index.js

@ -14,8 +14,8 @@ const dump = require('./utils/dump');
const isWebWorker = require('../utils/getEnvironment')('type') === 'webworker'; const isWebWorker = require('../utils/getEnvironment')('type') === 'webworker';
const setImage = require('./utils/setImage'); const setImage = require('./utils/setImage');
const defaultParams = require('./constants/defaultParams'); const defaultParams = require('./constants/defaultParams');
const defaultOutput = require('./constants/defaultOutput');
const { log, setLogging } = require('../utils/log'); const { log, setLogging } = require('../utils/log');
const arrayBufferToBase64 = require('./utils/arrayBufferToBase64');
const imageType = require('../constants/imageType'); const imageType = require('../constants/imageType');
const PSM = require('../constants/PSM'); const PSM = require('../constants/PSM');
@ -214,23 +214,44 @@ const getPDF = async ({ payload: { title, textonly } }, res) => {
res.resolve(getPDFInternal(title, textonly)); res.resolve(getPDFInternal(title, textonly));
}; };
const getImage = (type) => { // Combines default output with user-specified options and
api.WriteImage(type, '/image.png'); // counts (1) total output formats requested and (2) outputs that require OCR
const pngBuffer = TessModule.FS.readFile('/image.png'); const processOutput = (output) => {
const pngStr = `data:image/png;base64,${arrayBufferToBase64(pngBuffer.buffer)}`; const workingOutput = JSON.parse(JSON.stringify(defaultOutput));
TessModule.FS.unlink('/image.png'); // Output formats were set using `setParameters` in previous versions
return pngStr; // These settings are copied over for compatability
}; if (params.tessjs_create_box === "1") workingOutput.box = true;
if (params.tessjs_create_hocr === "1") workingOutput.hocr = true;
if (params.tessjs_create_osd === "1") workingOutput.osd = true;
if (params.tessjs_create_tsv === "1") workingOutput.tsv = true;
if (params.tessjs_create_unlv === "1") workingOutput.unlv = true;
const nonRecOutputs = ["imageColor", "imageGrey", "imageBinary"];
let recOutputCount = 0;
for (const prop in output) {
workingOutput[prop] = output[prop];
}
for (const prop in workingOutput) {
if (workingOutput[prop]) {
if (!nonRecOutputs.includes(prop)) {
recOutputCount++;
}
}
}
return {workingOutput, recOutputCount}
}
const recognize = async ({ const recognize = async ({
payload: { payload: {
image, options: { image, options: {
rectangle: rec, saveImageOriginal, saveImageGrey, saveImageBinary, savePDF, pdfTitle, rectangle: rec, pdfTitle,
pdfTextOnly, rotateAuto, rotateRadians, pdfTextOnly, rotateAuto, rotateRadians,
}, }, output
}, },
}, res) => { }, res) => {
try { try {
const {workingOutput, recOutputCount} = processOutput(output);
// When the auto-rotate option is True, setImage is called with no angle, // When the auto-rotate option is True, setImage is called with no angle,
// then the angle is calculated by Tesseract and then setImage is re-called. // then the angle is calculated by Tesseract and then setImage is re-called.
// Otherwise, setImage is called once using the user-provided rotateRadiansFinal value. // Otherwise, setImage is called once using the user-provided rotateRadiansFinal value.
@ -274,96 +295,14 @@ const recognize = async ({
if (typeof rec === 'object') { if (typeof rec === 'object') {
api.SetRectangle(rec.left, rec.top, rec.width, rec.height); api.SetRectangle(rec.left, rec.top, rec.width, rec.height);
} }
api.Recognize(null);
const result = dump(TessModule, api, params);
if (saveImageOriginal) {
result.imageOriginal = getImage(imageType.ORIGINAL);
} else {
result.imageOriginal = null;
}
if (saveImageGrey) {
result.imageGrey = getImage(imageType.GREY);
} else {
result.imageGrey = null;
}
if (saveImageBinary) {
result.imageBinary = getImage(imageType.BINARY);
} else {
result.imageBinary = null;
}
if (savePDF) {
result.pdf = getPDFInternal(pdfTitle ?? 'Tesseract OCR Result', pdfTextOnly ?? false);
} else {
result.pdf = null;
}
result.rotateRadians = rotateRadiansFinal;
res.resolve(result);
TessModule._free(ptr);
} catch (err) {
res.reject(err.toString());
}
};
// `threshold` is similar to `recognize` except it skips the recognition step if (recOutputCount > 0) {
// Useful for getting rotated/binarized images without running recognition api.Recognize(null);
const threshold = async ({
payload: {
image, options: {
rectangle: rec, saveImageOriginal, saveImageGrey, saveImageBinary, rotateAuto, rotateRadians,
},
},
}, res) => {
try {
let ptr;
let rotateRadiansFinal;
if (rotateAuto) {
const psmInit = api.GetPageSegMode();
let psmEdit = false;
if (![PSM.AUTO, PSM.AUTO_ONLY, PSM.OSD].includes(psmInit)) {
psmEdit = true;
api.SetVariable('tessedit_pageseg_mode', String(PSM.AUTO));
}
ptr = setImage(TessModule, api, image);
api.FindLines();
const rotateRadiansCalc = api.GetAngle();
// Restore user-provided PSM setting
if (psmEdit) {
api.SetVariable('tessedit_pageseg_mode', String(psmInit));
}
// Small angles (<0.005 radians/~0.3 degrees) are ignored to save on runtime
if (Math.abs(rotateRadiansCalc) >= 0.005) {
rotateRadiansFinal = rotateRadiansCalc;
ptr = setImage(TessModule, api, image, rotateRadiansFinal);
} else {
rotateRadiansFinal = 0;
}
} else {
rotateRadiansFinal = rotateRadians || 0;
ptr = setImage(TessModule, api, image, rotateRadiansFinal);
}
if (typeof rec === 'object') {
api.SetRectangle(rec.left, rec.top, rec.width, rec.height);
}
const result = {};
if (saveImageOriginal) {
result.imageOriginal = getImage(imageType.ORIGINAL);
} else {
result.imageOriginal = null;
}
if (saveImageGrey) {
result.imageGrey = getImage(imageType.GREY);
} else {
result.imageGrey = null;
}
if (saveImageBinary) {
result.imageBinary = getImage(imageType.BINARY);
} else { } else {
result.imageBinary = null; log(`Skipping recognition: all output options requiring recognition are disabled.`);
} }
const result = dump(TessModule, api, workingOutput, {pdfTitle, pdfTextOnly});
result.rotateRadians = rotateRadiansFinal; result.rotateRadians = rotateRadiansFinal;
res.resolve(result); res.resolve(result);
TessModule._free(ptr); TessModule._free(ptr);
@ -372,6 +311,7 @@ const threshold = async ({
} }
}; };
const detect = async ({ payload: { image } }, res) => { const detect = async ({ payload: { image } }, res) => {
try { try {
const ptr = setImage(TessModule, api, image); const ptr = setImage(TessModule, api, image);
@ -451,7 +391,6 @@ exports.dispatchHandlers = (packet, send) => {
initialize, initialize,
setParameters, setParameters,
recognize, recognize,
threshold,
getPDF, getPDF,
detect, detect,
terminate, terminate,

274
src/worker-script/utils/dump.js

@ -7,6 +7,8 @@
* @author Guillermo Webster <gui@mit.edu> * @author Guillermo Webster <gui@mit.edu>
* @author Jerome Wu <jeromewus@gmail.com> * @author Jerome Wu <jeromewus@gmail.com>
*/ */
const arrayBufferToBase64 = require('./arrayBufferToBase64');
const imageType = require('../../constants/imageType');
/** /**
* deindent * deindent
@ -37,13 +39,7 @@ const deindent = (html) => {
* @function dump recognition result to a JSON object * @function dump recognition result to a JSON object
* @access public * @access public
*/ */
module.exports = (TessModule, api, { module.exports = (TessModule, api, output, options) => {
tessjs_create_hocr,
tessjs_create_tsv,
tessjs_create_box,
tessjs_create_unlv,
tessjs_create_osd,
}) => {
const ri = api.GetIterator(); const ri = api.GetIterator();
const { const {
RIL_BLOCK, RIL_BLOCK,
@ -65,135 +61,161 @@ module.exports = (TessModule, api, {
.map((e) => e.slice(prefix.length + 1))[0] .map((e) => e.slice(prefix.length + 1))[0]
); );
ri.Begin(); const getImage = (type) => {
do { api.WriteImage(type, '/image.png');
if (ri.IsAtBeginningOf(RIL_BLOCK)) { const pngBuffer = TessModule.FS.readFile('/image.png');
const poly = ri.BlockPolygon(); const pngStr = `data:image/png;base64,${arrayBufferToBase64(pngBuffer.buffer)}`;
let polygon = null; TessModule.FS.unlink('/image.png');
// BlockPolygon() returns null when automatic page segmentation is off return pngStr;
if (TessModule.getPointer(poly) > 0) { };
const n = poly.get_n();
const px = poly.get_x(); const getPDFInternal = (title, textonly) => {
const py = poly.get_y(); const pdfRenderer = new TessModule.TessPDFRenderer('tesseract-ocr', '/', textonly);
polygon = []; pdfRenderer.BeginDocument(title);
for (let i = 0; i < n; i += 1) { pdfRenderer.AddImage(api);
polygon.push([px.getValue(i), py.getValue(i)]); pdfRenderer.EndDocument();
TessModule._free(pdfRenderer);
return TessModule.FS.readFile('/tesseract-ocr.pdf');
};
if (output.blocks) {
ri.Begin();
do {
if (ri.IsAtBeginningOf(RIL_BLOCK)) {
const poly = ri.BlockPolygon();
let polygon = null;
// BlockPolygon() returns null when automatic page segmentation is off
if (TessModule.getPointer(poly) > 0) {
const n = poly.get_n();
const px = poly.get_x();
const py = poly.get_y();
polygon = [];
for (let i = 0; i < n; i += 1) {
polygon.push([px.getValue(i), py.getValue(i)]);
}
/*
* TODO: find out why _ptaDestroy doesn't work
*/
// TessModule._ptaDestroy(TessModule.getPointer(poly));
} }
/*
* TODO: find out why _ptaDestroy doesn't work block = {
*/ paragraphs: [],
// TessModule._ptaDestroy(TessModule.getPointer(poly)); text: ri.GetUTF8Text(RIL_BLOCK),
confidence: ri.Confidence(RIL_BLOCK),
baseline: ri.getBaseline(RIL_BLOCK),
bbox: ri.getBoundingBox(RIL_BLOCK),
blocktype: enumToString(ri.BlockType(), 'PT'),
polygon,
};
blocks.push(block);
}
if (ri.IsAtBeginningOf(RIL_PARA)) {
para = {
lines: [],
text: ri.GetUTF8Text(RIL_PARA),
confidence: ri.Confidence(RIL_PARA),
baseline: ri.getBaseline(RIL_PARA),
bbox: ri.getBoundingBox(RIL_PARA),
is_ltr: !!ri.ParagraphIsLtr(),
};
block.paragraphs.push(para);
}
if (ri.IsAtBeginningOf(RIL_TEXTLINE)) {
textline = {
words: [],
text: ri.GetUTF8Text(RIL_TEXTLINE),
confidence: ri.Confidence(RIL_TEXTLINE),
baseline: ri.getBaseline(RIL_TEXTLINE),
bbox: ri.getBoundingBox(RIL_TEXTLINE),
};
para.lines.push(textline);
} }
if (ri.IsAtBeginningOf(RIL_WORD)) {
const fontInfo = ri.getWordFontAttributes();
const wordDir = ri.WordDirection();
word = {
symbols: [],
choices: [],
block = { text: ri.GetUTF8Text(RIL_WORD),
paragraphs: [], confidence: ri.Confidence(RIL_WORD),
text: ri.GetUTF8Text(RIL_BLOCK), baseline: ri.getBaseline(RIL_WORD),
confidence: ri.Confidence(RIL_BLOCK), bbox: ri.getBoundingBox(RIL_WORD),
baseline: ri.getBaseline(RIL_BLOCK),
bbox: ri.getBoundingBox(RIL_BLOCK),
blocktype: enumToString(ri.BlockType(), 'PT'),
polygon,
};
blocks.push(block);
}
if (ri.IsAtBeginningOf(RIL_PARA)) {
para = {
lines: [],
text: ri.GetUTF8Text(RIL_PARA),
confidence: ri.Confidence(RIL_PARA),
baseline: ri.getBaseline(RIL_PARA),
bbox: ri.getBoundingBox(RIL_PARA),
is_ltr: !!ri.ParagraphIsLtr(),
};
block.paragraphs.push(para);
}
if (ri.IsAtBeginningOf(RIL_TEXTLINE)) {
textline = {
words: [],
text: ri.GetUTF8Text(RIL_TEXTLINE),
confidence: ri.Confidence(RIL_TEXTLINE),
baseline: ri.getBaseline(RIL_TEXTLINE),
bbox: ri.getBoundingBox(RIL_TEXTLINE),
};
para.lines.push(textline);
}
if (ri.IsAtBeginningOf(RIL_WORD)) {
const fontInfo = ri.getWordFontAttributes();
const wordDir = ri.WordDirection();
word = {
symbols: [],
choices: [],
text: ri.GetUTF8Text(RIL_WORD), is_numeric: !!ri.WordIsNumeric(),
confidence: ri.Confidence(RIL_WORD), in_dictionary: !!ri.WordIsFromDictionary(),
baseline: ri.getBaseline(RIL_WORD), direction: enumToString(wordDir, 'DIR'),
bbox: ri.getBoundingBox(RIL_WORD), language: ri.WordRecognitionLanguage(),
is_numeric: !!ri.WordIsNumeric(), is_bold: fontInfo.is_bold,
in_dictionary: !!ri.WordIsFromDictionary(), is_italic: fontInfo.is_italic,
direction: enumToString(wordDir, 'DIR'), is_underlined: fontInfo.is_underlined,
language: ri.WordRecognitionLanguage(), is_monospace: fontInfo.is_monospace,
is_serif: fontInfo.is_serif,
is_smallcaps: fontInfo.is_smallcaps,
font_size: fontInfo.pointsize,
font_id: fontInfo.font_id,
font_name: fontInfo.font_name,
};
const wc = new TessModule.WordChoiceIterator(ri);
do {
word.choices.push({
text: wc.GetUTF8Text(),
confidence: wc.Confidence(),
});
} while (wc.Next());
TessModule.destroy(wc);
textline.words.push(word);
}
is_bold: fontInfo.is_bold, // let image = null;
is_italic: fontInfo.is_italic, // var pix = ri.GetBinaryImage(TessModule.RIL_SYMBOL)
is_underlined: fontInfo.is_underlined, // var image = pix2array(pix);
is_monospace: fontInfo.is_monospace, // // for some reason it seems that things stop working if you destroy pics
is_serif: fontInfo.is_serif, // TessModule._pixDestroy(TessModule.getPointer(pix));
is_smallcaps: fontInfo.is_smallcaps, if (ri.IsAtBeginningOf(RIL_SYMBOL)) {
font_size: fontInfo.pointsize, symbol = {
font_id: fontInfo.font_id, choices: [],
font_name: fontInfo.font_name, image: null,
}; text: ri.GetUTF8Text(RIL_SYMBOL),
const wc = new TessModule.WordChoiceIterator(ri); confidence: ri.Confidence(RIL_SYMBOL),
do { baseline: ri.getBaseline(RIL_SYMBOL),
word.choices.push({ bbox: ri.getBoundingBox(RIL_SYMBOL),
text: wc.GetUTF8Text(), is_superscript: !!ri.SymbolIsSuperscript(),
confidence: wc.Confidence(), is_subscript: !!ri.SymbolIsSubscript(),
}); is_dropcap: !!ri.SymbolIsDropcap(),
} while (wc.Next()); };
TessModule.destroy(wc); word.symbols.push(symbol);
textline.words.push(word); const ci = new TessModule.ChoiceIterator(ri);
} do {
symbol.choices.push({
text: ci.GetUTF8Text(),
confidence: ci.Confidence(),
});
} while (ci.Next());
// TessModule.destroy(i);
}
} while (ri.Next(RIL_SYMBOL));
TessModule.destroy(ri);
// let image = null; }
// var pix = ri.GetBinaryImage(TessModule.RIL_SYMBOL)
// var image = pix2array(pix);
// // for some reason it seems that things stop working if you destroy pics
// TessModule._pixDestroy(TessModule.getPointer(pix));
if (ri.IsAtBeginningOf(RIL_SYMBOL)) {
symbol = {
choices: [],
image: null,
text: ri.GetUTF8Text(RIL_SYMBOL),
confidence: ri.Confidence(RIL_SYMBOL),
baseline: ri.getBaseline(RIL_SYMBOL),
bbox: ri.getBoundingBox(RIL_SYMBOL),
is_superscript: !!ri.SymbolIsSuperscript(),
is_subscript: !!ri.SymbolIsSubscript(),
is_dropcap: !!ri.SymbolIsDropcap(),
};
word.symbols.push(symbol);
const ci = new TessModule.ChoiceIterator(ri);
do {
symbol.choices.push({
text: ci.GetUTF8Text(),
confidence: ci.Confidence(),
});
} while (ci.Next());
// TessModule.destroy(i);
}
} while (ri.Next(RIL_SYMBOL));
TessModule.destroy(ri);
return { return {
text: api.GetUTF8Text(), text: output.text ? api.GetUTF8Text() : null,
hocr: tessjs_create_hocr === '1' ? deindent(api.GetHOCRText()) : null, hocr: output.hocr ? deindent(api.GetHOCRText()) : null,
tsv: tessjs_create_tsv === '1' ? api.GetTSVText() : null, tsv: output.tsv ? api.GetTSVText() : null,
box: tessjs_create_box === '1' ? api.GetBoxText() : null, box: output.box ? api.GetBoxText() : null,
unlv: tessjs_create_unlv === '1' ? api.GetUNLVText() : null, unlv: output.unlv ? api.GetUNLVText() : null,
osd: tessjs_create_osd === '1' ? api.GetOsdText() : null, osd: output.osd ? api.GetOsdText() : null,
pdf: output.pdf ? getPDFInternal(options.pdfTitle ?? 'Tesseract OCR Result', options.pdfTextOnly ?? false) : null,
imageColor: output.imageColor ? getImage(imageType.COLOR) : null,
imageGrey: output.imageColor ? getImage(imageType.GREY) : null,
imageBinary: output.imageColor ? getImage(imageType.BINARY) : null,
confidence: api.MeanTextConf(), confidence: api.MeanTextConf(),
blocks, blocks: output.blocks ? blocks : null,
psm: enumToString(api.GetPageSegMode(), 'PSM'), psm: enumToString(api.GetPageSegMode(), 'PSM'),
oem: enumToString(api.oem(), 'OEM'), oem: enumToString(api.oem(), 'OEM'),
version: api.Version(), version: api.Version(),

Loading…
Cancel
Save