Web Standards & a11y
ISO/IEC 18004Reed-SolomonWebRTCSVGOffline-PWA

QR-Code-Generator & Webcam-Transfer – Statische Codes und optische Datenbrücke lokal im Browser

Lokaler QR-Code-Generator ohne Ablaufdatum: Statische SVG- und PNG-Codes mit Kontrastprüfung erzeugen oder längere Texte per Webcam-QR-Stream übertragen.

LKLukas Kopischke
Zuletzt aktualisiert am
QR-Studio & Optischer Datentransfer100 % Lokal · Kein Ablaufdatum
Vorlage:
Reed-Solomon Fehlerkorrektur~15 % Redundanz

Empfohlener Standard für Print & Web

Farben & Kontrast-Prüfung17.7:1
Statisch · 0 Server-Redirects26 Bytes
Vorschau wird berechnet…
Alle Berechnungen laufen lokal im Browser – ohne Werbung oder Account-Zwang.

Du druckst einen vermeintlich kostenlosen QR-Code auf 500 Einladungen oder Speisekarten – und zwei Wochen später zeigt der Scan plötzlich eine Bezahlschranke statt deiner Webseite. Oder du möchtest eine Konfigurationsdatei, einen öffentlichen SSH-Schlüssel oder ein WLAN-Passwort auf ein zweites Gerät bringen, ohne Cloud-Dienst, Messenger-Konto oder USB-Stick dazwischenzuschalten.

Ein statischer QR-Code nach ISO/IEC 18004 kodiert deine Zeichenkette samt Fehlerkorrektur-Bytes direkt als Schwarz-Weiß-Matrix im Bild und kommt ohne fremden Weiterleitungsserver aus. Für größere Textmengen, Fotos und Dateien bis 1 MB verpackt ein optischer Frame-Stream Dateiname, MIME-Typ und Rohbytes in nummerierte, per CRC-16 gesicherte Einzel-QR-Codes (bei Fotos auf Wunsch vorab lokal per Canvas-WebP auf rund 20–35 QR-Pakete geschrumpft), die eine Webcam in beliebiger Reihenfolge abfilmt und lokal zusammensetzt.

Merksatz

Statische QR-Codes laufen niemals ab, weil die Zieladresse direkt im Punktmuster steckt statt hinter einer fremden Kurz-URL. Reicht ein einzelnes Quadrat für längere Texte oder Dateien nicht mehr aus, überträgt eine Schleife nummerierter QR-Frames die Daten rein optisch von Bildschirm zu Kamera.

Warum manche „kostenlose“ QR-Codes ablaufen und wie die Matrix wirklich funktioniert

Ein QR-Code kennt technisch kein Verfallsdatum. Wenn ein gedruckter Code nach einer Testphase plötzlich den Dienst verweigert, hast du keinen direkten Link kodiert, sondern einen dynamischen QR-Code: Im Bild steckt dann eine fremde Kurz-URL wie https://qr-anbieter.example/x7k9p, die erst auf dem Server des Anbieters auf dein eigentliches Ziel weiterleitet. Schaltet der Betreiber diese Weiterleitung ab, wird jeder Druck unbrauchbar.

Kodierst du deine echte Zieladresse oder ein standardisiertes Schema wie WIFI:T:WPA;S:MeinNetz;P:Geheim;; direkt in die Matrix, entsteht ein statischer QR-Code. Solange deine eigene Zieladresse existiert, bleibt das Muster unbegrenzt lesbar – nachträglich ändern lässt sich das Ziel auf bereits gedrucktem Papier allerdings nicht mehr, sofern du keine Weiterleitung auf deiner eigenen Domain einrichtest.

Fehlerkorrektur, Ruhezone und Polarität

Damit ein Code trotz Kratzern, Kaffeeflecken oder ungünstigem Kamerawinkel lesbar bleibt, ergänzt der Generator zusätzliche Prüfbytes über eine . Vier Stufen sind im Standard festgelegt:

  • Stufe L (~7 % Redundanz): Kleinste Modulanzahl; sinnvoll für lange URLs auf sauberen Bildschirmen.
  • Stufe M (~15 % Redundanz): Ausgewogener Standard für Visitenkarten, Flyer und Web.
  • Stufe Q (~25 % Redundanz): Robuste Wahl für Aufkleber, Werkstätten oder leicht gewölbte Flächen.
  • Stufe H (~30 % Redundanz): Höchste Reserve, erzeugt aber deutlich kleinere Einzelpunkte und erfordert sauberen Druck.

Ebenso entscheidend für zuverlässiges Scannen sind die sowie die Helligkeitspolarität: Der ISO-Standard erwartet dunkle Module auf hellem Grund. Viele Smartphone-Apps lesen heute zwar auch weiße Codes auf schwarzem Hintergrund, ältere Handscanner an Kassen oder Einlasskontrollen scheitern daran jedoch regelmäßig. Für verlässliche Lesbarkeit sollte das Kontrastverhältnis mindestens 4,5:1 betragen – dieselbe rechnerische Grundlage wie im Leitfaden zu Accessibility & BITV 2.0.

Wie die optische QR-Datenbrücke Texte und Dateien ohne Startsignal überträgt

Theoretisch fasst ein einzelner QR-Code der Version 40 bis zu 2.953 Bytes. Praktisch verschmelzen die winzigen Punkte auf normalen Laptop-Displays und Handykameras aber oft schon ab 350 bis 600 Bytes zu einem kaum fokussierbaren Flimmern.

Um dennoch Konfigurationsdateien, Fotos, Screenshots oder Schlüssel rein optisch über einen zu schicken, verpackt der Sender Dateiname, MIME-Typ und Rohbytes in einen kompakten Binär-Umschlag (2 Bytes Header-Länge + JSON-Metadaten + Datei-Bytes), teilt diesen in Pakete von 160 bis 950 Bytes auf und spielt sie mit bis zu 12 FPS als Endlosschleife ab. Große Kamerafotos (bis 25 MB) schrumpft eine vorgeschaltete <canvas>-WebP-Stufe direkt im Arbeitsspeicher auf rund 18 bis 30 KB – das entspricht bei 950 Bytes Paketgröße nur etwa 20 bis 32 QR-Codes:

TYPESCRIPT
1// Binärer LKQR2-Umschlag für Texte & Dateien inklusive CRC-16-CCITT-Sicherung
2export function crc16Ccitt(bytes: Uint8Array): string {
3 let crc = 0xffff;
4 for (let i = 0; i < bytes.length; i++) {
5 crc ^= bytes[i] << 8;
6 for (let bit = 0; bit < 8; bit++) {
7 crc = (crc & 0x8000) !== 0 ? ((crc << 1) ^ 0x1021) & 0xffff : (crc << 1) & 0xffff;
8 }
9 }
10 return crc.toString(16).padStart(4, "0");
11}
12
13export function buildOpticalFileFrames(
14 fileName: string,
15 mimeType: string,
16 fileBytes: Uint8Array,
17 maxChunkBytes = 160
18): string[] {
19 const headerBytes = new TextEncoder().encode(
20 JSON.stringify({ k: "file", n: fileName, t: mimeType })
21 );
22 const envelope = new Uint8Array(2 + headerBytes.length + fileBytes.length);
23 envelope[0] = (headerBytes.length >> 8) & 0xff;
24 envelope[1] = headerBytes.length & 0xff;
25 envelope.set(headerBytes, 2);
26 envelope.set(fileBytes, 2 + headerBytes.length);
27
28 const crcHex = crc16Ccitt(envelope);
29 const sessionId = `${crcHex}${envelope.length.toString(36)}`;
30 const total = Math.ceil(envelope.length / maxChunkBytes);
31
32 return Array.from({ length: total }, (_, i) => {
33 const slice = envelope.slice(i * maxChunkBytes, (i + 1) * maxChunkBytes);
34 const base64 = btoa(String.fromCharCode(...slice));
35 // Format: Protokoll | Sitzung | Paket/Gesamt | Gesamt-CRC16 | Base64-Paket
36 return `LKQR2|${sessionId}|${i + 1}/${total}|${crcHex}|${base64}`;
37 });
38}

Woher weiß der Empfänger, wo der Anfang ist? Gar nicht über einen speziellen Start-Trigger, sondern über Selbstbeschreibung jedes einzelnen Bildes: Jedes QR-Paket trägt seine exakte Position (4/12), die Gesamtzahl (12) und die Session-ID im Klartext-Kopf. Schaltest du die Kamera mitten in der Schleife erst bei Paket 7 ein, legt der Browser sofort ein Map-Register für 12 Plätze an, liest 7..12 und im direkt anschließenden Schleifendurchlauf 1..6. Sobald alle Plätze gefüllt sind, sortiert er die Blöcke numerisch von 1 bis 12, prüft die CRC-16-Summe über den gesamten Datenstrom, liest ab Byte 0 den Dateinamen aus und bietet die Datei sofort zum Herunterladen an. Wie solche Werkzeuge dauerhaft als installierbare Web-App bereitstehen, vertieft Offline-KI & lokale Web-Apps.

Wann eignet sich ein QR-Code – und wann ist ein anderes Verfahren überlegen?

VerfahrenTypische DatenmengeNetzwerk nötig?StärkenKlare Grenze / Bessere Alternative
Statischer Einzel-QR20 – 350 BytesNein (beim Erstellen & Scannen)Unbegrenzt haltbar, kein Drittanbieter, in 0,2 s erfasstZiel nach dem Drucken nicht änderbar (außer über eigene Weiterleitungs-URL)
Eigene Weiterleitungs-URL im QR25 – 60 Bytes (deine-domain.de/go)Beim Aufruf des ZielsKleine, extrem leicht scanbare Matrix + Ziel auf eigenem Server änderbarHängt dauerhaft vom Weiterbetrieb deiner eigenen Domain ab
Optischer QR-Frame-Stream0,4 – 150 KB (Rohdaten bis 1 MB)Komplett ohne Netz (nur Bildschirm + Kamera)Einweg-Übertragung für Texte, Configs & WebP-komprimierte Fotos (~25 QR-Codes) ohne Funk/CloudBegrenzte optische Bandbreite (~2–8 KB/s); ungeeignet für Videos oder große ZIP-Archive
Lokales WLAN / WebRTC (z. B. LocalSend / PairDrop)Megabyte bis GigabyteGleiches lokales NetzTausendfach schneller, bidirektional mit echter DateiprüfungScheitert in getrennten Gäste-/Firmen-VLANs oder bei strikter Funk-Sperre
Saubere Praxis für Print & Transfer
  • Für Drucksachen immer SVG exportieren, damit Kanten im Layoutprogramm gestochen scharf bleiben
  • Willst du ein Druckziel später ändern können, verlinke auf eine kurze Route deiner eigenen Domain statt auf fremde Gratis-Portale
  • Beim Kamera-Stream moderate 4 FPS und 160 Bytes Paketgröße wählen – das schlägt zu dichte Einzelbilder mit vielen Scan-Wiederholungen
Typische Fehlerquellen
  • Keine fremden Kurz-URL-Generatoren für Schilder, Visitenkarten oder Vereinsflyer ohne Einsicht in die Ziel-URL verwenden
  • Keine hellen QR-Punkte auf dunklem oder stark gemustertem Foto-Hintergrund ohne helle Ruhezone platzieren
  • Keine sensiblen Zugangsdaten oder privaten Schlüssel in serverseitige Online-Generatoren kopieren
Einweg-Natur des optischen Streams beachten

Da die Kamera des Empfängers kein Funksignal an den Sender zurückschickt, weiß der sendende Bildschirm nicht, welches Paket dem Empfänger noch fehlt. Für Fotos empfiehlt sich deshalb die integrierte WebP-Stufe „Kompakt“ (~20–35 QR-Pakete, ein Umlauf dauert bei 8 FPS nur ~3–4 Sekunden) statt unkomprimierter Megabyte-Originale.

Prüfpunkte vor Druck oder Datenübertragung

  • Inhalt vor dem Druck gegenprüfen: Scanne den fertigen Code mit der Standard-Kamera-App und lies die angezeigte Ziel-URL im Klartext – steht dort wirklich deine eigene Domain statt eines Weiterleitungsdienstes?
  • Mindestgröße und Kontrast einhalten: Auf Papier mindestens 2 × 2 cm Kantenlänge (bei langen vCards lieber 3 × 3 cm), dunkle Module auf hellem Grund und mindestens 4,5:1 Kontrast wählen.
  • WLAN-Sonderzeichen testen: Enthält dein WLAN-Passwort Semikolon (;), Doppelpunkt (:) oder Backslash (\), prüfe den Verbindungsaufbau einmal real an iOS und Android.
  • Optischen Stream blendfrei abfilmen: Beim Webcam-Transfer Bildschirmhelligkeit erhöhen und schräges Gegenlicht vermeiden, damit der Belichtungsmesser der Kamera das Raster nicht überstrahlt.

Quellen und nächste Schritte