diff --git a/README.md b/README.md index 46c0406..3453a11 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ beim physischen Sortieren am Tisch anleitet: Modul vor die Kamera halten, die App nennt den Stapel. Vor dem Scannen wählt der Nutzer eine von drei Funktionen — Strichcode, -2D-Code oder Text erkennen (siehe „Funktionsweise" unten). Jede Funktion nutzt +QR-Code oder Text erkennen (siehe „Funktionsweise" unten). Jede Funktion nutzt ausschließlich ihre eigene Quelle; anders als früher weicht die App nicht mehr automatisch auf Texterkennung aus, wenn kein Code gefunden wird. @@ -65,21 +65,20 @@ keine Daten verlassen das Gerät. | Funktion | Liest | Laufende Suche | Texterkennung | |---|---|---|---| | **Strichcode** | Code128, Code39, Code93, ITF, EAN-13, EAN-8, UPC-A, UPC-E, Codabar | ja | nein | - | **2D-Code** | QRCode, MicroQRCode, RMQRCode, DataMatrix, Aztec, PDF417 | ja | nein | + | **QR-Code** | QRCode, MicroQRCode, RMQRCode, DataMatrix, Aztec, PDF417 | ja | nein | | **Text erkennen** | keine Codes | nein | ja, auf Knopfdruck | - „2D-Code" liest neben den QR-Varianten auch DataMatrix, Aztec und PDF417. - Ursprünglich war die Funktion (damals „QR-Code" beschriftet) auf QR - beschränkt; am Gerät zeigte sich, dass sie damit auf der eigenen Ware nichts - fand, weil die 2D-Codes auf den RAM-Etiketten DataMatrix sind. Die - Beschriftung wurde daraufhin auf „2D-Code" geändert, damit sie nicht mehr - verspricht, was sie nicht meint. Die interne Kennung heißt weiterhin - `qrcode` (aus historischen Gründen, siehe `src/scan-modes.js`) — daran - ändert die Erweiterung nichts. + „QR-Code" heißt auf Wunsch des Auftraggebers „QR-Code", liest aber bewusst + nicht nur QR-Varianten, sondern auch DataMatrix, Aztec und PDF417. Der + Grund: Die 2D-Codes auf den RAM-Etiketten sind DataMatrix, nicht QR — eine + auf QR beschränkte Funktion fände auf dieser Ware nichts. Die interne + Kennung heißt weiterhin `qrcode` (aus historischen Gründen, siehe + `src/scan-modes.js`), und der Name ist Absicht — es ist der Wunsch des + Auftraggebers für seinen Sprachgebrauch. „Modul scannen" erscheint nur in „Text erkennen" — in „Strichcode" und - „2D-Code" sucht die App ohnehin laufend, ein Knopf ohne Texterkennung hätte - dort nichts zu tun. Der Zielrahmen hebt sich in „Strichcode" und „2D-Code" + „QR-Code" sucht die App ohnehin laufend, ein Knopf ohne Texterkennung hätte + dort nichts zu tun. Der Zielrahmen hebt sich in „Strichcode" und „QR-Code" hervor, sobald ein passender Code im Bild ist; in „Text erkennen" bleibt er schlicht, weil dort nichts laufend erkannt wird. Ein Wechsel der Funktion während des Sortierens (z. B. bei gemischter Ware) gilt sofort: laufende @@ -89,7 +88,7 @@ keine Daten verlassen das Gerät. nach dem Fortsetzen (siehe Punkt 5 unten) und erst danach die Funktionswahl — die Kamera startet in jedem Fall erst, nachdem beides geklärt ist. - Technisch bekommen „Strichcode" und „2D-Code" eine Texterkennung + Technisch bekommen „Strichcode" und „QR-Code" eine Texterkennung hineingereicht, die sofort leeren Text liefert, ohne Tesseract anzustoßen; „Text erkennen" bekommt eine Barcode-Dekodierung hineingereicht, die sofort eine leere Liste liefert (`buildRecognitionAdapters` in @@ -97,7 +96,7 @@ keine Daten verlassen das Gerät. Punkte 1–4 unten) bleibt dabei unverändert und kennt keine Funktionen — die drei Funktionen unterscheiden sich ausschließlich darin, welche Adapter ihr übergeben werden. -1. **Barcode-Dekodierung** (nur in „Strichcode" und „2D-Code"). Die zur +1. **Barcode-Dekodierung** (nur in „Strichcode" und „QR-Code"). Die zur Funktion gehörenden Codearten werden laufend aus dem Kamerabild dekodiert (`zxing-wasm`, `decodeBarcodes` in `src/barcode.js` bekommt die Codearten der gewählten Funktion übergeben). Das ist exakt, im Gegensatz zu @@ -106,7 +105,7 @@ keine Daten verlassen das Gerät. App rät nicht, sondern fragt nach. Das gilt nur für Barcodes mit einem bekannten Nummernschema; widersprechen sich mehrere Barcodes mit unbekanntem Nummernschema, wird keine ihrer Teilenummern übernommen. -2. **Teilenummer-Decoder** (nur relevant in „Strichcode"/„2D-Code" — „Text +2. **Teilenummer-Decoder** (nur relevant in „Strichcode"/„QR-Code" — „Text erkennen" liest nie einen Barcode, siehe Punkt 0). Aus einer Hersteller-PN wie `M386A8K40BM1-CRC4Y` werden Kapazität, Bauform und Geschwindigkeit tabellengesteuert abgeleitet. Gelingt das, entfällt OCR vollständig, das Ergebnis ist grün. @@ -137,7 +136,7 @@ keine Daten verlassen das Gerät. die aus dem erkannten Text abgeleiteten technischen Angaben (Kapazität, Bauform, Rank, Geschwindigkeit) über die Stapelzuordnung (`specsCompatible` in `src/spec.js`) — anders als in „Strichcode"/ - „2D-Code", wo meist die exakte Teilenummer trägt. + „QR-Code", wo meist die exakte Teilenummer trägt. 4. **Stapel-Zuweisung.** Grün (Barcode) und Gelb (OCR) laufen ohne Eingabe durch; nur bei roter Konfidenz (nichts Eindeutiges erkannt, widersprüchliche Barcodes oder widersprüchliche unbekannte Barcodes ohne jede OCR-Kapazität) @@ -194,9 +193,9 @@ und toleranter Vergleich, OCR-Bildaufbereitung (Otsu-Schwellwert) und -Feldextraktion, Stapel-Zuweisung, die Erkennungs-Pipeline samt Zeitgrenzen und Mehrdeutigkeitsbehandlung, die Sitzungssicherung samt Prüfung eines wiederhergestellten Zustands, die drei Scan-Funktionen (`scan-modes.js` — -Codearten je Funktion, DataMatrix/Aztec/PDF417 in „2D-Code") sowie die je Funktion +Codearten je Funktion, DataMatrix/Aztec/PDF417 in „QR-Code") sowie die je Funktion tatsächlich aufgerufenen Adapter (`scan-recognition.js` — Texterkennung läuft -nachweislich nie in „Strichcode"/„2D-Code", Barcode-Dekodierung nachweislich +nachweislich nie in „Strichcode"/„QR-Code", Barcode-Dekodierung nachweislich nie in „Text erkennen"). Kamera, Barcode-/OCR-Adapter selbst, die Auswahl-Oberfläche und die Verdrahtung in `main.js` laufen nur im echten Browser und werden dort manuell geprüft (siehe „Am Gerät noch zu prüfen" @@ -265,8 +264,8 @@ worauf du bei der Veröffentlichung achten solltest. | `src/ocr-extract.js` | OCR-Rohtext → Spec-Felder | | `src/session.js` | Stapel halten, vorschlagen, buchen, umsortieren, zurücknehmen — inklusive der aus den Einträgen abgeleiteten, je Stapel bekannten Barcode-Inhalte (`stack.codes`), die vor dem Vergleich der technischen Angaben über die Zuordnung entscheiden, sofern diese Angaben nicht widersprechen | | `src/pipeline.js` | Barcode → Teilenummer → OCR → Ampelfarbe, inkl. Zeitgrenzen, Mehrdeutigkeitsbehandlung und Kurzschluss über einen bereits bekannten Barcode-Inhalt (`deps.isKnownCode`) — unverändert; kennt keine Scan-Funktionen | -| `src/scan-modes.js` | Die drei Scan-Funktionen (Strichcode, 2D-Code, Text erkennen): Kennung, deutsche Beschriftung, gelesene Codearten, laufende Suche ja/nein, Texterkennung ja/nein — einzige Quelle, sowohl für die Auswahl-Oberfläche als auch für `main.js` | -| `src/scan-recognition.js` | Baut die an `recognize()` übergebenen Adapter anhand der gewählten Funktion: in „Strichcode"/„2D-Code" liefert die Texterkennung sofort leeren Text ohne Tesseract anzustoßen, in „Text erkennen" liefert die Barcode-Dekodierung sofort eine leere Liste ohne `zxing-wasm` anzustoßen | +| `src/scan-modes.js` | Die drei Scan-Funktionen (Strichcode, QR-Code, Text erkennen): Kennung, deutsche Beschriftung, gelesene Codearten, laufende Suche ja/nein, Texterkennung ja/nein — einzige Quelle, sowohl für die Auswahl-Oberfläche als auch für `main.js` | +| `src/scan-recognition.js` | Baut die an `recognize()` übergebenen Adapter anhand der gewählten Funktion: in „Strichcode"/„QR-Code" liefert die Texterkennung sofort leeren Text ohne Tesseract anzustoßen, in „Text erkennen" liefert die Barcode-Dekodierung sofort eine leere Liste ohne `zxing-wasm` anzustoßen | | `src/storage.js` | Absturzschutz der laufenden Sitzung: sichert und lädt aus `localStorage`, verwirft beim Laden jeden in sich unstimmigen Zustand vollständig (siehe unten) | | `src/camera.js` | Kamerastart, Einzelbildaufnahme, Bilddatei-Ersatzweg | | `src/barcode.js` | Adapter zu `zxing-wasm`; `decodeBarcodes(imageData, formats)` bekommt die Codearten übergeben, ohne Angabe wie bisher (Code128 + DataMatrix) | @@ -392,14 +391,14 @@ werden: **Funktionswahl (neu)** - Erster Start ohne gesicherte Sitzung: Auswahl mit drei großen Flächen - („Strichcode", „2D-Code", „Text erkennen") erscheint, *bevor* die Kamera + („Strichcode", „QR-Code", „Text erkennen") erscheint, *bevor* die Kamera startet — kein Kamerabild sichtbar, solange keine Funktion gewählt ist. - Erster Start *mit* gesicherter Sitzung: erst die Frage „Gesicherte Sitzung gefunden" (fortsetzen/verwerfen), erst danach die Funktionswahl. - „Strichcode" wählen: laufende Suche erkennt Code-128/Code-39/EAN/UPC/…, kein „Modul scannen"-Knopf sichtbar, Zielrahmen hebt sich bei erkanntem Code hervor. -- „2D-Code" wählen und ein Etikett mit dem eigenen DataMatrix-Code vor die +- „QR-Code" wählen und ein Etikett mit dem eigenen DataMatrix-Code vor die Kamera halten: Rahmen hebt sich hervor, Treffer wird gebucht (DataMatrix liest diese Funktion jetzt mit). Einen echten QR-Code vor dieselbe Funktion halten: ebenfalls Treffer. @@ -421,7 +420,7 @@ werden: Etikettenfoto tatsächlich brauchbaren Text (bisher nur an synthetischen Testbildern geprüft, nie an einem echten Foto). - Ladezeit des WASM-Barcode-Moduls (`zxing-wasm`) beim allerersten Scan einer - Sitzung in Funktion „Strichcode" oder „2D-Code" beobachten — bleibt sie + Sitzung in Funktion „Strichcode" oder „QR-Code" beobachten — bleibt sie deutlich unter der 10-Sekunden-Zeitgrenze der Pipeline, und braucht ein zweiter, schnell nachfolgender Scan nicht erneut die volle Ladezeit (Beleg, dass die Vorbereitung tatsächlich nur einmal läuft)? In Funktion „Text @@ -434,7 +433,7 @@ werden: - Ladezeit des Tesseract-Arbeiters beim ersten Antippen von „Modul scannen" in Funktion „Text erkennen" beobachten — bleibt sie auf einem normalen Handy deutlich unter der 20-Sekunden-Zeitgrenze der Pipeline? In den - Funktionen „Strichcode"/„2D-Code" darf dieses Laden nie anlaufen, auch + Funktionen „Strichcode"/„QR-Code" darf dieses Laden nie anlaufen, auch nicht bei einem gänzlich unbekannten Etikett, da `runOcr` dort nie aufgerufen wird. - Verfügbarkeitsanzeige der Texterkennung: bleibt nach einem erfolgreichen @@ -443,7 +442,7 @@ werden: darauf zurück? - Stichprobe, ob die feste Zeichen-Whitelist der Texterkennung auf echten Etiketten keine tatsächlich benötigten Zeichen ausschließt. -- Funktion „Strichcode"/„2D-Code": kein passender Code im Bild führt zu +- Funktion „Strichcode"/„QR-Code": kein passender Code im Bild führt zu Rot-Dialog (statt Fehler oder Absturz) — hier ohne jeden OCR-Versuch. Funktion „Text erkennen": kein verwertbarer OCR-Text führt ebenfalls zu Rot, hier ohne jeden Barcode-Versuch. diff --git a/src/scan-modes.js b/src/scan-modes.js index 2f7a59f..dddb5bd 100644 --- a/src/scan-modes.js +++ b/src/scan-modes.js @@ -38,8 +38,11 @@ export const SCAN_MODES = [ // Kennung bleibt aus historischen Gruenden `qrcode`, obwohl die Funktion // inzwischen alle 2D-Codearten liest (nicht mehr nur QR) - Umbenennung // nicht vorgenommen, da `qrcode` an mehreren Stellen durchgereicht wird. + // Label heisst auf Wunsch des Auftraggebers "QR-Code", obwohl die Funktion + // bewusst auch DataMatrix, Aztec und PDF417 liest - die RAM-Etiketten + // tragen DataMatrix, nicht QR. id: 'qrcode', - label: '2D-Code', + label: 'QR-Code', // QR-Varianten plus DataMatrix, Aztec, PDF417 - siehe Kommentar am Kopf. barcodeFormats: ['QRCode', 'MicroQRCode', 'RMQRCode', 'DataMatrix', 'Aztec', 'PDF417'], continuousSearch: true, diff --git a/test/scan-modes.test.js b/test/scan-modes.test.js index feb63c5..4206d64 100644 --- a/test/scan-modes.test.js +++ b/test/scan-modes.test.js @@ -17,9 +17,9 @@ test('Funktion 1 (Strichcode): eindimensionale Codearten, laufende Suche, keine assert.equal(mode.useOcr, false); }); -test('Funktion 2 (2D-Code): QR-Varianten und DataMatrix, Aztec, PDF417', () => { +test('Funktion 2 (QR-Code): QR-Varianten und DataMatrix, Aztec, PDF417', () => { const mode = getScanMode('qrcode'); - assert.equal(mode.label, '2D-Code'); + assert.equal(mode.label, 'QR-Code'); assert.deepEqual(mode.barcodeFormats, [ 'QRCode', 'MicroQRCode', 'RMQRCode', 'DataMatrix', 'Aztec', 'PDF417', ]);