feat: OCR-Adapter mit Bildaufbereitung

preprocess() rechnet rein (Graustufen, Kontrastspreizung, Schwellwert) ohne
DOM-Zugriff und ist damit ohne Browser testbar. runOcr() ist der Browser-
Adapter, cacht den Tesseract-Arbeiter und laesst isOcrAvailable() sich nach
einem Fehlschlag wieder erholen statt dauerhaft einzufrieren - analog zum
ensureReady()-Muster in barcode.js.
This commit is contained in:
vchuser
2026-07-28 16:43:49 +02:00
parent 87d7f7c393
commit 65f699a704
2 changed files with 160 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { preprocess } from '../src/ocr.js';
/** Minimaler ImageData-Ersatz, damit der Test ohne Browser laeuft. */
function image(pixels) {
const data = new Uint8ClampedArray(pixels.length * 4);
pixels.forEach((value, i) => {
data[i * 4] = value;
data[i * 4 + 1] = value;
data[i * 4 + 2] = value;
data[i * 4 + 3] = 255;
});
return { width: pixels.length, height: 1, data };
}
test('preprocess erzeugt ein reines Schwarz-Weiss-Bild', () => {
const result = preprocess(image([10, 40, 200, 250]));
for (let i = 0; i < result.data.length; i += 4) {
const value = result.data[i];
assert.ok(value === 0 || value === 255, `Pixel ${i / 4} ist ${value}`);
assert.equal(result.data[i + 1], value);
assert.equal(result.data[i + 2], value);
assert.equal(result.data[i + 3], 255);
}
});
test('preprocess trennt dunkle von hellen Pixeln', () => {
const result = preprocess(image([10, 40, 200, 250]));
assert.equal(result.data[0], 0, 'dunkelstes Pixel wird schwarz');
assert.equal(result.data[12], 255, 'hellstes Pixel wird weiss');
});
test('preprocess laesst Breite und Hoehe unveraendert', () => {
const result = preprocess(image([0, 128, 255]));
assert.equal(result.width, 3);
assert.equal(result.height, 1);
});