Notizbuch mit Kamera, Stimme und OCR — lokal selbst gebaut
Ich habe meiner Heim-App Bild-Uploads, polnische Spracheingabe und Texterkennung aus Fotos (OCR) hinzugefügt. Alles läuft lokal, ohne externe APIs.

Der Artikel beschreibt Funktionen aus Home App v2.12 — einer Heim-App auf einem privaten Server. Der Code ist nicht öffentlich, aber die beschriebenen Muster (TipTap Image, Web Speech API, Tesseract.js) sind allgemein anwendbar.
Hintergrund
Ein Rezept auf einem Zettel, ein Beleg zum Abrechnen, eine Idee beim Kochen — früher landeten sie in der Kamerarolle des Handys oder gingen schlicht verloren.
Seit einigen Monaten nutze ich das Notizbuch in Home App intensiv — eine eigene Web-App, die auf meinem Heimserver läuft. Eine Sache fehlte mir: ein Bild einfügen, eine Notiz mit der Handykamera aufnehmen, einen Gedanken schnell per Sprache diktieren oder eine Datei (z. B. PDF) an eine Notiz anhängen zu können.
Ich nutze kommerzielle Apps (Notion, Obsidian, Evernote), und jede kann etwas davon — aber meine Daten bleiben beim Anbieter. Ich wollte dasselbe, nur lokal.
Vier Wege, ein Bild einzufügen
Vor der Umsetzung beherrschte das Notizbuch nur Text ( mit ein paar Erweiterungen: Aufgabenlisten, Überschriften, Links). Ich habe vier Upload-Kanäle ergänzt:
1. Drag & Drop — zieh eine Bilddatei auf den Editor. Es erscheint ein violetter gestrichelter Rahmen als Drop-Zone. Loslassen → das Bild landet auf dem Server und wird im Editor eingefügt.
2. Dateiauswahl — eine Schaltfläche in der Toolbar öffnet den System-Dateidialog. Unter Android zeigt er die Galerie. Auf dem iPhone akzeptiert er auch HEIC (das native Format der Apple-Kamera).
3. Kamera — eine zweite Schaltfläche in der Toolbar (capture=environment) öffnet direkt die
rückseitige Handykamera. Keine Zwischenschritte.
4. Aus der Zwischenablage einfügen — Strg+V (oder langes Drücken → Einfügen am Telefon) nach
einem Screenshot oder einem kopierten Bild fügt es direkt ein. Im Browser über das
Clipboard-Paste-Event von TipTap unterstützt.
Wie es serverseitig funktioniert
Bilder gehen über multer (Express, in-memory, 25 MB Limit) an einen Dienst, der sharp nutzt:
- Original mit vollständigen EXIF-Daten gespeichert
- Display-Variante: max. 1920 px, JPEG q85, EXIF-Rotation angewendet
- Thumbnail: max. 400 px, JPEG q80
Deduplizierung über SHA-256 — dieselbe Datei zweimal hochgeladen = eine Datei auf der Platte, zwei Referenzen. Der Speicher liegt in einem bind-gemounteten Host-Verzeichnis und ist vom Standard-Backup des Homelabs erfasst.
Neben Bildern nimmt derselbe Endpoint auch normale Dateien (z. B. PDF) an — diese überspringen die
sharp-Verarbeitung und erscheinen in der Notiz als herunterladbarer Anhang (die
Büroklammer-Schaltfläche in der Toolbar). Die Liste erlaubter MIME-Typen wird serverseitig geprüft.
Polnische Spracheingabe
Die Web Speech API (SpeechRecognition) ist in Chrome und Edge eingebaut — keine Abhängigkeiten,
keine Serverkosten. Ich habe eine Mikrofon-Schaltfläche in die Toolbar des Notizbuchs eingefügt:
- Klick auf Start → pulsierender roter Punkt + „Słucham…" („Ich höre zu…")
- Jeder erkannte Satz wird direkt in den Editor eingefügt
continuous: true+interimResults: true→ Text-Streaming in Echtzeit- Sprache:
pl-PLfest codiert
Für alltägliche Notizen funktioniert es überraschend gut. Bei Fachvokabular (z. B. englische Fachbegriffe mitten im polnischen Satz) wird es schlechter — aber zum Festhalten von Ideen, To-dos und schnellen Notizen reicht es völlig.
Safari iOS unterstützt die Web Speech API nicht — die Mikrofon-Schaltfläche wird dann automatisch ausgeblendet.
OCR aus einem Foto (Tesseract.js)
Eine dritte neue Schaltfläche startet die Texterkennung:
- Du wählst ein Foto (Kamera oder Datei)
- Das Foto wird auf den Server hochgeladen (Standard-Pipeline mit sharp)
- Tesseract.js läuft als Web Worker im Browser
- Das Modell
pol+eng(~15 MB, nach dem ersten Download in IndexedDB zwischengespeichert) - OCR liefert Text → es erscheint ein Modal mit:
- einklappbarer Bildvorschau
- bearbeitbarem Textfeld mit dem erkannten Text
- drei Schaltflächen: nur Bild / nur Text / beides (Standard)
Ein wichtiges Detail: erhält die display-Variante vom Server (JPEG nach EXIF-Rotation),
nicht das rohe HEIC vom iPhone — das macht heic2any im Browser überflüssig.
Genauigkeit: hervorragend bei gedrucktem Text, akzeptabel bei lesbarer Handschrift, schwach bei unleserlichem Gekritzel. Für die Zukunft habe ich die Anbindung von Vision als Option „Besseres OCR (KI)" vorgesehen — der Endpoint ist bereits vorbereitet und wartet auf ein Modell.
FAB Quick-Capture
Eine schwebende +-Schaltfläche auf der Startseite (unten rechts) plus das Tastenkürzel n — du
erstellst eine Notiz, ohne erst den Notizbuch-Bereich zu öffnen. Vier Aktionen im Bottom Sheet:
- Notiz → leerer Editor
- Foto → Kamera → Upload → Notiz mit Bild
- Sprache → leere Notiz + Mikrofon startet automatisch
- OCR → Kamera → Upload → OCR-Modal
Die Notizen landen im Standard-Notizbuch des Nutzers. Hat der Nutzer noch kein Standard-Notizbuch, legt das Backend „Szybkie notatki" („Schnelle Notizen") an und setzt es als Standard.
Notizen verlinken
Nach Fotos, OCR und Quick-Capture fehlte mir noch eine Sache: Notizen miteinander zu
verknüpfen. Kein gewöhnlicher URL-Link, sondern wie in Obsidian: ich tippe [[,
beginne einen Titel, wähle eine Notiz aus den Vorschlägen, und im Text erscheint ein
kleiner violetter Chip mit dem Link.
Ein Klick darauf springt direkt zur verlinkten Notiz. Und öffne ich diese Notiz, sehe ich ein Panel „Verlinkungen" — eine Liste aller Stellen, die auf sie verweisen. Das Notizbuch ist damit nicht mehr nur eine chronologische Liste von Einträgen, sondern fühlt sich eher wie ein kleines, privates Wiki an: Ein Thema kann eine eigene Notiz haben, und andere Einträge können darauf zurückverweisen, ohne den Kontext zu kopieren.
Technisch gibt es dafür keine eigene Relationstabelle. Ein Link ist ein TipTap-Knoten
in content_json, und Verlinkungen werden durch einen JSON-Scan in PostgreSQL
ermittelt (jsonb_path_exists). Bei der Größe eines privaten Notizbuchs ist das
einfacher, als eine zusätzliche Kantentabelle bei jedem Autosave synchron zu halten —
sollte das Linkvolumen mal deutlich wachsen, wäre das der Punkt, es zu überdenken.
Dabei habe ich auch ein paar Dinge rund um Bilder abgeschlossen:
- Bildergalerie — eine Notiz mit mehreren Fotos zeigt einen Vorschaustreifen und eine Vollbildansicht.
- Bildgröße ändern — am Eck-Handle ziehen, live skalieren und in der gewünschten Größe in der Notiz lassen.
- Markdown-Export — eine fertige Notiz als
.mdherunterladen, inklusive Text-Darstellung von Links und Anhängen.
Was ich gelernt habe
nginx client_max_body_size — der Standardwert ist 1 MB. Ich hatte vergessen, ihn zu setzen,
also wurden Handy-Fotos (typisch 3–5 MB) stillschweigend abgewiesen. Jetzt client_max_body_size 30m.
useLayoutEffect statt useEffect für die Scroll-Position — ich hatte eine Komponente mit
horizontalem Snap-Scroll (Dashboard-Seiten). Die Startposition über useEffect + requestAnimationFrame
zu setzen, schlug fehl, weil clientWidth zu diesem Zeitpunkt 0 war. useLayoutEffect +
scrollLeft = index * window.innerWidth läuft synchron vor dem ersten Rendern.
prev_content_json — nach dem Deployment entdeckte ich, dass das Autosave den Inhalt einer Notiz
überschreiben kann, wenn der Nutzer sie während eines App-Neustarts geöffnet hat. Ich habe eine Spalte
prev_content_json hinzugefügt — bei jedem Update wird zuerst die vorherige Version des Inhalts
atomar dorthin gesichert. Gedacht war das als einmaliger Notfall-Rückgriff, und später, beim Einbau
der Notizen-Verlinkung, hat es tatsächlich meine Daten gerettet.
Was als Nächstes kommt
- Ollama Vision für schwierige OCR-Fälle (sobald ein Modell verfügbar ist)
- Versionsverlauf (mehr als ein Schritt zurück)
- PWA Share Target — „An Notizbuch teilen" aus dem Android-Teilen-Menü
Das Notizbuch ist nur ein Modul von Home App. Wie aus einem Einkaufsproblem im Haushalt eine ganze Familien-App wurde, beschreibe ich in der Fallstudie zum Familien-Dashboard.
Home App läuft auf einem privaten x86-Server. Stack: React 19 + TipTap 3 + Express + PostgreSQL.
Häufige Fragen
Landen meine Fotos und Notizen in der Cloud?
Nein. Bild-Upload, Diktat und OCR laufen lokal auf dem Heimserver — die Daten verlassen das Zuhause nicht.
Brauche ich teure Hardware für OCR und Diktat?
Nein. OCR läuft im Browser (Tesseract.js) und das Diktat nutzt die eingebaute Web Speech API. Ein gewöhnlicher Heimserver genügt.
Kann ich PDFs anhängen und mit dem Handy fotografieren?
Ja. Das Notizbuch unterstützt Datei-Upload, Screenshots, Handy-Fotos und das Ziehen von Bildern direkt in den Editor.