Change QR-Code function label from "2D-Code" back to "QR-Code"

The function keeps reading all 2D-code types (QR-Code, MicroQRCode, RMQRCode,
DataMatrix, Aztec, PDF417) as requested. The label is now "QR-Code" per the
client's preference for their terminology. Added clarifying comments explaining
the intentional mismatch between the name and the supported formats, since the
hardware labels use DataMatrix (not QR). Updated README and test accordingly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-29 14:50:24 +02:00
co-authored by Claude Opus 5
parent 2d7778cea8
commit 3907204209
3 changed files with 30 additions and 28 deletions
+24 -25
View File
@@ -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 14 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.
+4 -1
View File
@@ -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,
+2 -2
View File
@@ -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',
]);