---
title: "Codes auf einem Bild-Stream lesen (experimentell)"
product: "LumiScan QR Code Reader"
component: "lumiscan-qr-code-reader-de"
version: "1.0.0"
display_version: "1.0.0.5"
latest_version: true
language: "de"
url: "https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html"
---

# Codes auf einem Bild-Stream lesen (experimentell) – LumiScan QR Code Reader

> [!IMPORTANT]
> Der Bild-Stream ist **experimentell**. Seine Knoten und Einstellungen können sich noch ändern. Verwenden Sie ihn zur Evaluierung, und prüfen Sie ihn mit Ihren Kameras und Ihrem Data Layer, bevor Sie sich auf ihn verlassen.

`execute` liest ein Bild pro Aufruf: Ihr Programm setzt `input/image-address` und schreibt in `execute`. Ein Bild-Stream funktioniert andersherum. Der Cam Driver veröffentlicht jedes Bild, das er aufnimmt, auf `<camera name>/control/publish/output/stream/frame`, mit seiner Größe, seinem Pixelformat und seiner Lineage (siehe das Handbuch des Cam Driver, *Bilder streamen*). Der Reader abonniert den Stream einer Kamera, liest jeden QR-Code in jedem Frame, sobald er eintrifft, und veröffentlicht ein Ergebnis pro Frame auf `control/subscribe/output/stream/result`.

Jeder Frame wird genau so gelesen, wie `execute` ein Bild liest. `execute` hat keine Eingabe außer der Bildadresse, und an deren Stelle tritt der Frame. `input/parameter` wird von keinem der beiden gelesen: siehe [Data-Layer-Referenz](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/datalayer-reference.html).

Jedes Ergebnis trägt die Lineage seines Frames - welche Kamera ihn aufgenommen hat, in welchem Lauf des Kamera-Streams, als welchen Frame des Laufs - ergänzt um den eigenen Schritt des Readers. Siehe [Die Lineage eines Ergebnisses](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#lineage).

Standardmäßig fällt der Reader nie hinter seine Kamera zurück. Treffen Frames schneller ein, als der Reader sie liest, nimmt er jedes Mal, wenn das vorherige Lesen beendet ist, den neuesten Frame. Die Frames dazwischen werden als übersprungen gezählt. Wie viele Frames warten dürfen, wird mit der Warteschlangengröße festgelegt, siehe [Die Warteschlangengröße](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#queue-size).

Wie Streams in allen LumiScan-Apps funktionieren - Produzenten und Konsumenten, Starten und Stoppen, die Lineage - ist unter [Streams](https://docs.hdvisionsystems.com/de/lumiscan-keryx-de/1.0.0/streams.html) im Handbuch LumiScan Keryx beschrieben. Diese Seite beschreibt den Stream des Readers.

## Die Knoten des Streams {#addresses}

Der Reader hat die Knoten des Streams, ob er einen Stream abonniert oder nicht. Es ist kein Neustart nötig, um sie zu verwenden. Alle Adressen unten beginnen mit `hdvisionsystems/lumiscan-qr-code-reader/`. Es gibt keine Module: ein Stream pro Installation.

**Tabelle 1. Methoden**

| Adresse | Bedeutung |
| --- | --- |
| `control/subscribe/execute` | Prüft die fünf Eingaben von `control/subscribe` gemeinsam, speichert sie in der Einstellungsdatei des Readers und wendet sie dann an: Ein laufender Stream folgt in seinem nächsten Zyklus, ohne Neustart. Das Schreiben einer Eingabe allein ändert nichts. Siehe [Die Quelle ändern](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#subscribing). |
| `control/unsubscribe/execute` | Entfernt die in `control/unsubscribe/input/address` genannte Quelle, womit auch der Stream-Modus endet. Das Tag bleibt. Wird wie ein Subscribe in der Einstellungsdatei des Readers gespeichert. |

**Tabelle 2. Eingaben von control/subscribe**

| Adresse | Typ | Bedeutung |
| --- | --- | --- |
| `control/subscribe/input/enable` | bool | Stream-Modus: `true` lässt den Stream laufen, `false` stoppt ihn. |
| `control/subscribe/input/address` | string | Die eine Quelle: der Stream-Ordner einer Kamera, zum Beispiel `hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream`. Der Reader liest dessen Knoten `frame`. Eine andere Adresse ersetzt die Quelle. |
| `control/subscribe/input/tag` | string | Das Tag, das der Reader auf seine Ergebnisse setzt: Der Schritt des Readers in der Lineage jedes Ergebnisses trägt es, sodass jeder, der ein Ergebnis weiter hinten in der Kette liest, sieht, welches Modul es gelesen hat. Leer: der Name des Readers, `lumiscan-qr-code-reader`. Ein neues Tag markiert das nächste Ergebnis; die Quelle bleibt abonniert. |
| `control/subscribe/input/queue-size` | uint32 | Wie viele Frames warten dürfen, während ein Frame gelesen wird: `1` bis `64`. Siehe [Die Warteschlangengröße](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#queue-size). |
| `control/subscribe/input/keep-latest-output` | bool | `true`, um jedes Stream-Ergebnis zusätzlich in `output/results` zu schreiben. Siehe [Die neueste Ausgabe behalten](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#keep-latest-output). |

Die Eingaben beginnen mit dem, was beim Start der Anwendung angewendet ist, sodass ein Client eine davon ändern und ausführen kann.

Was die Quelle enthalten muss: Lesen Sie `system/meta/subscription-schema`. Es ist ein JSON Schema des Knotens `frame` der Quelle, eines `stream_image` mit seiner `lineage` und seinem `image`, in seiner JSON-Form. Siehe [Data-Layer-Referenz](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/datalayer-reference.html#system).

**Tabelle 3. Eingabe von control/unsubscribe**

| Adresse | Typ | Bedeutung |
| --- | --- | --- |
| `control/unsubscribe/input/address` | string | Die zu entfernende Quelle: die Adresse, die `setting/stream/address` zeigt. Ein `/` an einem der beiden Enden zählt nicht. |

**Tabelle 4. Einstellungen**

| Adresse | Typ | Bedeutung |
| --- | --- | --- |
| `setting/stream/enable`, `setting/stream/address`, `setting/stream/tag`, `setting/stream/queue-size`, `setting/stream/keep-latest-output` | wie die Eingaben | Was `control/subscribe/execute` oder `control/unsubscribe/execute` zuletzt angewendet hat, so wie die Einstellungsdatei es speichert. Schreibgeschützt. |
| `setting/settings-hash` | string | Der Hash dessen, womit die Ergebnisse erzeugt werden, als 16 Hexziffern. Schreibgeschützt. Siehe [Der Einstellungs-Hash](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#settings-hash). |

**Tabelle 5. Ausgaben**

| Adresse | Typ | Bedeutung |
| --- | --- | --- |
| `control/subscribe/output/stream/active` | bool | `true`, solange der Stream läuft. |
| `control/subscribe/output/stream/result` | flatbuffers `stream_codes` | Die aus jedem Frame gelesenen Codes und die Lineage des Frames. Abonnieren Sie ihn, um jedes Ergebnis zu erhalten. Siehe [Das Ergebnis eines Frames](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#result). |
| `control/subscribe/output/stream/last-failure` | string | Warum der letzte Frame, der nicht gelesen werden konnte, fehlgeschlagen ist. Nennt die Quelle mit ihrer Adresse, zum Beispiel `a frame of 'hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream' failed: …`. Wird beim Start des Streams geleert. |
| `control/subscribe/output/stream/statistics/…` | uint64 | Zähler des aktuellen oder des letzten Streams, siehe [Die Statistik lesen](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#statistics). |

> [!NOTE]
> `execute` schreibt in `output/results`, der Stream in `control/subscribe/output/stream/result` - Singular. Der Stream schreibt nur mit eingeschaltetem `keep-latest-output` auch in `output/results`.

## Einrichten {#setting-up}

1. Stellen Sie sicher, dass der Stream des Cam Driver läuft: Sein `hdvisionsystems/lumiscan-cam-driver/<camera name>/control/publish/output/stream/active` ist `true`.
2. Schreiben Sie den Stream-Ordner der Kamera, zum Beispiel `hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream`, in `control/subscribe/input/address`. Lassen Sie `control/subscribe/input/tag` leer, um die Ergebnisse mit dem Namen des Readers zu markieren, oder schreiben Sie ein eigenes Tag hinein.
3. Abonnieren Sie `control/subscribe/output/stream/result`.
4. Setzen Sie `control/subscribe/input/enable` auf `true` und schreiben Sie dann in `control/subscribe/execute`. Warten Sie, bis `control/subscribe/output/stream/active` `true` ist. Ab dann treffen die Ergebnisse ein.
5. Zum Stoppen setzen Sie `control/subscribe/input/enable` auf `false` und schreiben erneut in `control/subscribe/execute`. Der gerade gelesene Frame wird zuerst fertig gelesen.

Auf ctrlX OS nehmen Sie dieselben Schreibzugriffe in der Data-Layer-Ansicht der Weboberfläche von ctrlX OS oder aus Ihrem SPS-Programm vor.

Auf einem PC dieselben Schritte mit `krxclient`, dem Kommandozeilen-Client, der eine SPS vertritt (siehe [krxclient](https://docs.hdvisionsystems.com/de/lumiscan-keryx-de/1.0.0/tools.html#krxclient)). Ergänzen Sie die Optionen `--keryx-backend` und `--keryx-url`, die Ihr Broker benötigt:

```none
krxclient write hdvisionsystems/lumiscan-qr-code-reader/control/subscribe/input/address hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream
krxclient write hdvisionsystems/lumiscan-qr-code-reader/control/subscribe/input/enable true
krxclient execute hdvisionsystems/lumiscan-qr-code-reader/control/subscribe/execute
krxclient subscribe hdvisionsystems/lumiscan-qr-code-reader/control/subscribe/output/stream/result --count 5
```

`krxclient subscribe` zeigt einen FlatBuffer nur anhand seiner Größe. Es zeigt Ihnen, dass Ergebnisse eintreffen, nicht, was sie enthalten.

Gut zu wissen:

- Der Stream-Modus ist ein **Zustand**, kein Kommando: Der Stream läuft, solange das angewendete `enable` `true` ist.
- Der Stream kann vor dem Stream des Cam Driver gestartet werden. Ergebnisse treffen ein, sobald Frames eintreffen.
- Was `control/subscribe/execute` anwendet, wird in der Einstellungsdatei des Readers gespeichert. Nach einem Neustart der Anwendung startet der Reader, wie er war: Einer, der gestreamt hat, streamt sofort wieder, ohne dass Ihr Programm etwas ausführt. Siehe [In der Einstellungsdatei gespeichert](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#saving).

## Die Quelle ändern {#subscribing}

Ein Reader hat eine Quelle. Eine SPS oder ein anderer Client ändert sie, während die Anwendung läuft, mit oder ohne laufenden Stream:

1. Schreiben Sie die neuen Werte in die Eingaben von `control/subscribe` - nur die, die Sie ändern: Die anderen halten das, was angewendet ist.
2. Schreiben Sie in `control/subscribe/execute`. Die Eingaben werden gemeinsam geprüft, in der Einstellungsdatei des Readers gespeichert und erst dann angewendet: `setting/stream/` zeigt sie sofort, und ein laufender Stream folgt in seinem nächsten Zyklus. Eine andere Adresse ersetzt die Quelle; die Frames, die bei der alten Quelle warteten, werden als übersprungen gezählt. Ein neues Tag, eine neue Warteschlangengröße oder ein neues `keep-latest-output` braucht kein neues Abonnement: Ein neues Tag markiert das nächste Ergebnis.
3. Um die Quelle zu entfernen, schreiben Sie ihre Adresse in `control/unsubscribe/input/address` und dann in `control/unsubscribe/execute`. Damit endet der Stream-Modus. Die Eingaben von `control/subscribe` werden auf das gesetzt, was angewendet wurde: Stream-Modus aus, keine Adresse. Das Tag bleibt: Es markiert die Ergebnisse des Readers, nicht die Quelle.

Wenn die Einstellungsdatei nicht geschrieben werden kann, ändert sich nichts. Siehe [In der Einstellungsdatei gespeichert](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#saving).

Die Methoden antworten:

| ctrlX Data Layer | LumiScan Keryx | Wann |
| --- | --- | --- |
| `DL_OK` | `Ok` | Erledigt. |
| `DL_INVALID_VALUE` | `Rejected` | `control/subscribe/execute`: Stream-Modus ohne Adresse oder eine Warteschlangengröße außerhalb von `1` bis `64`. `control/unsubscribe/execute`: Die Adresse ist nicht die Quelle, oder es gibt keine Quelle. |
| `DL_CREATION_FAILED` | `CreationFailed` | Die Einstellungsdatei konnte nicht geschrieben werden, zum Beispiel weil sie kein gültiges JSON ist. Nichts hat sich geändert. |

Siehe auch [Ergebnisse eines Methodenaufrufs](https://docs.hdvisionsystems.com/de/lumiscan-keryx-de/1.0.0/status-codes.html#method-results).

Der Grund für eine Ablehnung wird in das Anwendungsprotokoll geschrieben.

Kann die Quelle nicht abonniert werden, versucht der Reader es alle 5 Sekunden erneut, solange der Stream läuft, und protokolliert den ersten Fehlschlag.

## Das Ergebnis eines Frames {#result}

`control/subscribe/output/stream/result` enthält eine FlatBuffers-Tabelle vom Typ `stream_codes` (Datei-Identifier `HSCD`), auf dem Data Layer registriert als `types/hdvisionsystems/lumiscan-qr-code-reader/stream_codes`. Ihr kompiliertes Schema wird als `bfbs/stream_codes.bfbs` installiert.

| Feld | Bedeutung |
| --- | --- |
| `lineage` | Woher das Ergebnis stammt, siehe [Die Lineage eines Ergebnisses](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#lineage). |
| `result` | Die Codes, als `CodeDetectResultArray`: dieselbe Tabelle, die `execute` für dasselbe Bild in `output/results` schreibt, beschrieben unter [Das Ergebnis](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/the-result.html). Ein Frame ohne QR-Code ergibt ein leeres Array `results`. |

Ein Lesen von `control/subscribe/output/stream/result` liefert das neueste Ergebnis; vor dem ersten Frame ein leeres. Das letzte Ergebnis bleibt nach dem Stopp des Streams stehen.

Ein Frame wird dekodiert, wie `execute` den Bildknoten dekodiert, es werden also dieselben Pixelformate akzeptiert, siehe [Voraussetzungen](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/requirements.html). Der gesamte Frame wird durchsucht. Ein Frame und dasselbe Bild, über `input/image-address` gelesen, ergeben dieselben Codes.

Ein Frame, der nicht gelesen werden kann - zum Beispiel einer in einem Pixelformat, das der Reader nicht unterstützt, oder einer, dessen Pixel die angegebene Größe nicht füllen - ergibt kein Ergebnis. Er wird in `statistics/failed-frames` gezählt, und `control/subscribe/output/stream/last-failure` nennt den Grund.

## Die Lineage eines Ergebnisses {#lineage}

`lineage.steps` listet auf, woher das Ergebnis stammt, der Ursprung zuerst:

1. Der Schritt der Kamera, wie der Cam Driver ihn erzeugt hat: `producer` ist die Adresse der Kamera, `hdvisionsystems/lumiscan-cam-driver/<camera name>`; `run`, wann der Stream der Kamera gestartet wurde; `sequence` die Nummer des Frames in diesem Lauf; `external_id` die eigene Frame-Nummer der Kamera; `settings_hash` die Einstellungen der Kamera; `tag` das Tag des Cam Driver für die Kamera, standardmäßig ihre Modul-ID, zum Beispiel `camera1`.
2. Der Schritt des Readers: `producer` ist die Adresse des Readers, `hdvisionsystems/lumiscan-qr-code-reader`; `run`, wann der Stream des Readers gestartet wurde (jeder Start ist ein neuer Lauf); `sequence` die Nummer des Ergebnisses im Lauf, ab `1`; `settings_hash` die Einstellungen des Readers, siehe [Der Einstellungs-Hash](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#settings-hash); `elapsed_us` die Mikrosekunden vom Eintreffen des Frames beim Reader bis zu seinem Ergebnis, Wartezeit eingeschlossen; `time_us`, wann das Ergebnis erzeugt wurde, in Mikrosekunden seit der Epoche; `tag` das Tag des Readers, `control/subscribe/input/tag`, oder `lumiscan-qr-code-reader`, wenn es leer ist.

Ein Ergebnis benennt seinen Frame also genau: die Kamera über `producer`, den Frame über `run` und `sequence`. Um zu wissen, von welcher Kamera ein Ergebnis stammt, lesen Sie den `producer` seines ersten Schritts. Eine Lücke in der `sequence` des Kamera-Schritts zwischen zwei Ergebnissen derselben Kamera sind Frames, die übersprungen wurden, fehlgeschlagen oder verloren sind.

Eine Lineage enthält höchstens 16 Schritte. Eine längere behält den Ursprung und die neuesten Schritte, und `dropped` zählt die ausgelassenen Schritte.

Ein Frame ohne Lineage ergibt ein Ergebnis nur mit dem Schritt des Readers. Ein Wert auf dem Knoten `frame` eines Streams, der kein `stream_image` ist, wird ignoriert und einmalig protokolliert.

## Der Einstellungs-Hash {#settings-hash}

`setting/settings-hash` und der `settings_hash` des Reader-Schritts in jedem Ergebnis identifizieren, womit die Ergebnisse erzeugt werden. Der Knoten zeigt den Hash als 16 Hexziffern; der Schritt enthält denselben Wert als Zahl.

Der Reader hat keine Einstellung, die ein Lesen verändert, daher umfasst der Hash nur den Codetyp sowie den Namen und die Version der Anwendung: Er ändert sich, wenn die Anwendung aktualisiert wird. Er umfasst nicht den Stream-Modus, die Quelle, die Warteschlangengröße oder keep-latest-output, die die Frames auswählen und takten.

Wenn ein Hash zum ersten Mal auftritt, schreibt der Reader die Einstellungen, für die er steht, nach `settings-history/qr-code-reader-<hash>.json` im Konfigurationsverzeichnis der Anwendung, sodass ein in einem Ergebnis gefundener Hash später nachgeschlagen werden kann. Die Anwendung löscht diese Dateien nicht. Eine Datei sieht so aus:

```json
{
    "format": 1,
    "settings": {
        "code-type": "qr-code",
        "software.name": "lumiscan-qr-code-reader",
        "software.version": "<version>"
    },
    "settingsHash": "<16 hex digits>"
}
```

## Die Statistik lesen {#statistics}

Die Zähler beginnen bei jedem Start des Streams bei null, werden etwa viermal pro Sekunde aktualisiert, solange er läuft, und behalten nach dem Stopp ihre letzten Werte. Alle Adressen beginnen mit `control/subscribe/output/stream/statistics/`.

| Zähler | Bedeutung |
| --- | --- |
| `elapsed-ms` | Millisekunden seit dem Start des Streams. Teilen Sie einen Zähler dadurch, um eine Rate zu erhalten. |
| `received-frames` | Frames, die das Abonnement geliefert hat. |
| `processed-frames` | Gelesene Frames, jeder mit einem auf `control/subscribe/output/stream/result` veröffentlichten Ergebnis. |
| `skipped-frames` | Nie gelesene Frames: von neueren aus der Warteschlange verdrängt, während ein Frame gelesen wurde (siehe [Die Warteschlangengröße](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#queue-size)), oder wartend, als die Quelle ersetzt oder entfernt wurde. |
| `failed-frames` | Frames, die nicht gelesen werden konnten. `control/subscribe/output/stream/last-failure` nennt den Grund für den letzten Fehlschlag, und das Protokoll nennt die Fehlschläge, höchstens eine Zeile alle 5 Sekunden. |
| `lost-frames` | Frames, die verworfen wurden, bevor sie eintrafen, ermittelt aus Lücken in der `sequence` der Kamera innerhalb eines Laufs ihres Streams. Eine neue Quelle oder ein neuer Lauf des Kamera-Streams beginnt die Zählung neu. |
| `processing-us` | Mikrosekunden, die alle Lesevorgänge zusammen gedauert haben. Teilen Sie durch `processed-frames` für den Mittelwert. |

Frames, die beim Stopp des Streams noch warten, werden verworfen, ohne gezählt zu werden.

## In der Einstellungsdatei gespeichert {#saving}

Stream-Modus und Quelle sind Einstellungen des Readers. Sie werden im Element `stream` der Einstellungsdatei des Readers gespeichert, `qr-code-reader.json` im Konfigurationsverzeichnis der Anwendung.

`control/subscribe/execute` und `control/unsubscribe/execute` speichern dort selbst, was sie anwenden, alle fünf Werte in einem Schreibvorgang, bevor sie sie anwenden. Wenn die Datei nicht geschrieben werden kann, antwortet die Methode mit `CreationFailed` (ctrlX `DL_CREATION_FAILED`), und nichts ändert sich. Nach einem Neustart abonniert der Reader dieselbe Quelle und startet, wenn `stream.enable` `true` ist, seinen Stream sofort: Niemand muss etwas ausführen.

Das Speichern ändert nur das Element `stream`; der Rest der Datei bleibt, wie er war, Kommentare eingeschlossen. Der Reader legt die Datei an, wenn es keine gibt.

Das Konfigurationsverzeichnis ist:

**Auf ctrlX OS:** `/var/snap/rexroth-solutions/common/solutions/activeConfiguration/lumiscan-qr-code-reader`.

**Auf einem PC (Windows):** `%APP_RESOURCE_DIR%\etc\lumiscan-qr-code-reader`; ohne `APP_RESOURCE_DIR` `C:\ProgramData\HD Vision Systems GmbH\LumiScan Vision Suite\lumiscan-qr-code\etc\lumiscan-qr-code-reader`.

Die Datei enthält ein Element, `stream`. Ein Beispiel - auf einem PC ist dies das Beispiel, das die Anwendung mit `--generate-settings` schreibt, siehe [Mit einem Beispiel beginnen](https://docs.hdvisionsystems.com/de/lumiscan-qr-code-reader-de/1.0.0/lumiscan-qr-code-reader/reading-codes-on-an-image-stream.html#generate-settings):

```json
{
    // The settings of the QR Code Reader, read once, at the start: the image stream it reads codes in.
    // control/subscribe/execute and control/unsubscribe/execute save what they change here before
    // they apply it, the rest of the file left as it is, comments included.
    "$schema": "schemas/qr-code-reader.schema.json",
    "stream": {
        // Stream mode: read every frame of the source as it arrives. Off if left out.
        "enable": false,
        // The one image stream to read: its folder.
        "address": "hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream",
        // "tag" (left out here): what marks the codes it reads, in their lineage - the reader's name,
        // lumiscan-qr-code-reader, if left out.
        // How many frames may wait while a frame is read: 1 to 64, 1 if left out.
        "queueSize": 1,
        // Each stream result also on output/results, as execute writes it. Off if left out.
        "keepLatestOutput": false
    }
}
```

| Schlüssel | Erforderlich | Bedeutung |
| --- | --- | --- |
| `enable` | Nein | Stream-Modus: `true` startet den Stream beim Start der Anwendung. Benötigt eine `address`. `false`, wenn weggelassen. |
| `address` | Nein | Die eine Quelle: der Stream-Ordner einer Kamera. |
| `tag` | Nein | Was die Ergebnisse des Readers markiert: das `tag` des Reader-Schritts in ihrer Lineage. Der Name des Readers, `lumiscan-qr-code-reader`, wenn weggelassen. |
| `queueSize` | Nein | Wie viele Frames warten dürfen: `1` bis `64`, `1`, wenn weggelassen. |
| `keepLatestOutput` | Nein | `true`, um jedes Stream-Ergebnis zusätzlich in `output/results` zu schreiben. `false`, wenn weggelassen. |
| `onEntry` | Nein | Die Schritte, die auf jeden eintreffenden Frame angewendet werden, jeder ein Objekt mit einem `kind`, wie der `stream` jeder LumiScan-Anwendung sie hat. Diese Anwendung hat noch keine: Lassen Sie es weg oder leer (`[]`). Ein Schritt startet den Reader außerhalb des Stream-Modus, mit einer Warnung im Protokoll; das Speichern behält ihn bei. |

`control/subscribe/execute` und `control/unsubscribe/execute` schreiben alle fünf.

Gut zu wissen:

- Die Datei wird einmal gelesen, beim Start der Anwendung. Änderungen, die von Hand an der Datei vorgenommen werden, wirken beim nächsten Start.
- Ein Wert, der nicht verwendet werden kann, wird ignoriert und protokolliert: ein `enable` oder `keepLatestOutput`, das nicht `true` oder `false` ist, eine `address` oder ein `tag`, das kein String ist, eine `queueSize` außerhalb von `1` bis `64` (`1` wird verwendet). Stream-Modus ohne `address` wird ignoriert: Der Reader startet außerhalb des Stream-Modus.
- Das Element `subscriptions` früherer Versionen wird nicht mehr gelesen, und der Reader protokolliert, dass es umgezogen ist: Geben Sie die Quelle als `address` an.
- Eine Datei, die kein gültiges JSON ist, wird ignoriert und protokolliert.

## Die Warteschlangengröße {#queue-size}

`control/subscribe/input/queue-size` legt fest, wie viele Frames warten dürfen, während ein Frame gelesen wird: `1` bis `64`, standardmäßig `1`. Sie wird als `stream.queueSize` gespeichert, und `setting/stream/queue-size` zeigt den verwendeten Wert. Ein Frame, der eintrifft, wenn so viele warten, verdrängt den ältesten von ihnen, der in `statistics/skipped-frames` gezählt wird. Eine neue Warteschlangengröße gilt ab dem nächsten eintreffenden Frame, ohne neues Abonnement.

| Warteschlangengröße | Wirkung |
| --- | --- |
| 1 (Standard) | Der Reader liest den neuesten Frame. Er fällt nie zurück; wenn das Lesen langsamer ist als die Kamera, überspringt er Frames. |
| Mehr als 1 | Kurze Schübe von Frames werden alle gelesen, und weniger werden übersprungen. Wenn das Lesen länger langsamer ist als die Kamera, fällt der Reader zurück: Er liest Frames, die bis zu so viele Lesevorgänge alt sind. Jeder wartende Frame hält ein ganzes Bild im Speicher. |

## Die neueste Ausgabe behalten {#keep-latest-output}

Mit `control/subscribe/input/keep-latest-output` `true` - angewendet durch `control/subscribe/execute`, gespeichert als `stream.keepLatestOutput` - schreibt der Reader jedes Stream-Ergebnis zusätzlich in `output/results`, so wie `execute` es schreibt, sobald das Ergebnis auf `control/subscribe/output/stream/result` veröffentlicht ist. Ein Client, der `output/results` liest, hat dann das Ergebnis des neuesten Frames, ohne den Stream zu abonnieren. Es kostet eine Kopie jedes Ergebnisses. Standardmäßig aus.

## execute, während der Stream läuft {#while-streaming}

`execute` und der Stream halten einander nicht auf. Jeder Frame wird von einem eigenen Detektor gelesen, wie jeder Aufruf von `execute`, und nichts wird zwischen beiden geteilt: `execute` kann jederzeit aufgerufen werden, während der Stream läuft, und ein Frame wartet nie darauf.

## Einschränkungen {#limitations}

- `input/parameter` wird weder von `execute` noch vom Stream gelesen.
- (ctrlX OS, Ubuntu) Der Stream wurde nicht auf Linux, auf dem ctrlX Data Layer oder mit einer echten Kamera verifiziert.
- (PC) Der Stream wurde nur auf Windows mit LumiScan Keryx und simulierten Bildern getestet. Er wurde nicht mit einer echten Kamera verifiziert.
- LumiScan Cockpit zeichnet die Ergebnisse des Streams noch nicht.
- Änderungen, die von Hand an der Einstellungsdatei vorgenommen werden, wirken beim nächsten Start der Anwendung.

## Mit einem Beispiel beginnen (PC) {#generate-settings}

Auf einem PC schreibt der QR Code Reader ein Beispiel seiner Einstellungen in einen Ordner Ihrer Wahl und beendet sich, ohne zu starten. Zum Beispiel (Windows):

```shell
lumiscan-qr-code --generate-settings C:\work\qr-code-reader-settings
```

Ohne Ordner (`-g` allein) schreibt er in den aktuellen Ordner. Das Beispiel ist die Einstellungsdatei `qr-code-reader.json`: Stream-Modus aus, der Stream der `camera1` des Cam Driver als Quelle, die standardmäßige Warteschlangengröße und `keep-latest-output` aus. Daneben, in `schemas/`, liegen das Schema, das sie in `"$schema"` nennt, `qr-code-reader.schema.json`, und `stream.schema.json`, das den Abschnitt `stream` beschreibt; ein Editor, der JSON Schema versteht, kann die Datei dagegen prüfen. Kopieren Sie den Ordner `schemas` mit. Vorhandene Dateien werden nie überschrieben: Ist eine davon bereits im Ordner, wird nichts geschrieben, und der QR Code Reader nennt, welche.

Der QR Code Reader nennt dann den Ordner, aus dem er seine Einstellungen liest, auf Windows standardmäßig `C:\ProgramData\HD Vision Systems GmbH\LumiScan Vision Suite\lumiscan-qr-code\etc\lumiscan-qr-code-reader`. Bearbeiten Sie das Beispiel, kopieren Sie es dorthin, und starten Sie den QR Code Reader.
