Handschrifterkennung von Nutzern

Mit der Handwriting Recognition API können Sie Text in handschriftlichen Eingaben sofort erkennen.

Was ist die Handwriting Recognition API?

Mit der Handschrifterkennungs-API können Sie die Handschrift (Tinte) Ihrer Nutzer in Text umwandeln. In einigen Betriebssystemen sind solche APIs schon lange enthalten, und mit dieser neuen Funktion können Ihre Web-Apps diese Funktion nutzen. Die Conversion findet direkt auf dem Gerät des Nutzers statt, ohne dass Sie Bibliotheken oder Dienste von Drittanbietern hinzufügen müssen.

Dieses API implementiert sogenannte oder nahezu in Echtzeit. Das bedeutet, dass der werden handschriftliche Eingaben erkannt, während die Nutzenden sie zeichnen, indem sie die Schwimmzüge. Im Gegensatz zu „offline“ wie die optische Zeichenerkennung (Optical Character Recognition, OCR), nur das Endprodukt bekannt ist, können Online-Algorithmen aufgrund zusätzliche Signale wie die zeitliche Abfolge und der Druck einzelner Tintenstriche.

Empfohlene Anwendungsfälle für die Handwriting Recognition API

Anwendungsbeispiele:

  • Notizenanwendungen, in denen Nutzer handschriftliche Notizen erfassen und übersetzen lassen möchten in Text umwandeln.
  • Google Formulare-Anwendungen, bei denen Nutzer aus Zeitgründen Stift oder Finger eingeben können.
  • Spiele, bei denen Buchstaben oder Zahlen eingegeben werden müssen, z. B. Kreuzworträtsel, Galgenmännchen oder Sudoku.

Aktueller Status

Die Handwriting Recognition API ist bei Chromium 99 verfügbar.

Handschrifterkennungs-API verwenden

Funktionserkennung

Prüfen Sie, ob die Methode createHandwritingRecognizer() vorhanden ist, um die Browserunterstützung zu ermitteln für das navigator-Objekt:

if ('createHandwritingRecognizer' in navigator) {
  // 🎉 The Handwriting Recognition API is supported!
}

Wichtige Konzepte

Die Handwriting Recognition API wandelt handschriftliche Eingaben unabhängig von der Eingabemethode in Text um. (Maus, Tippen, Stift) Die API hat vier Hauptentitäten:

  1. Ein Punkt gibt an, wo sich der Mauszeiger zu einem bestimmten Zeitpunkt befand.
  2. Eine Strich besteht aus einem oder mehreren Punkten. Die Aufzeichnung eines Strichs beginnt, wenn der Nutzer den Mauszeiger nach unten bewegen (d.h., er klickt auf die primäre Maustaste oder berührt den Bildschirm mit dem Stift oder Finger) und endet, wenn sie den Zeiger wieder nach oben heben.
  3. Eine Zeichnung besteht aus einem oder mehreren Strichen. Die tatsächliche Erkennung findet auf dieser Ebene statt.
  4. Der Erkennungscode wurde mit der erwarteten Eingabesprache konfiguriert. Damit wird eine Instanz erstellt einer Zeichnung mit angewendeter Erkennungskonfiguration.

Diese Konzepte werden als spezifische Schnittstellen und Wörterbücher implementiert, auf die ich gleich noch eingehen werde.

Die Kernentitäten der Handschrifterkennungs-API: Ein oder mehrere Punkte bilden einen Strich, mindestens ein Strich stellt eine Zeichnung dar, die vom Erkennungsmodul erstellt wird. Die eigentliche Erkennung erfolgt auf Zeichnungsebene.

Erkennung erstellen

Um Text aus handschriftlichen Eingaben zu erkennen, müssen Sie eine Instanz eines HandwritingRecognizer durch Aufrufen von navigator.createHandwritingRecognizer() und Übergeben von Einschränkungen hinzufügen. Das zu verwendende Handschrifterkennungsmodell wird durch Einschränkungen bestimmt. Derzeit haben Sie können Sie eine Liste mit Sprachen angeben, die nach Präferenz sortiert sind:

const recognizer = await navigator.createHandwritingRecognizer({
  languages: ['en'],
});

Die Methode gibt ein Versprechen zurück, das mit einer Instanz eines HandwritingRecognizer aufgelöst wird, wenn der Browser Ihre Anfrage erfüllen kann. Andernfalls wird das Versprechen mit einem Fehler abgelehnt und Die Handschrifterkennung ist nicht verfügbar. Aus diesem Grund sollten Sie das Erkennung bestimmter Erkennungsfunktionen zuerst.

Unterstützung der Erkennungserkennung wird abgefragt

Durch Aufrufen von navigator.queryHandwritingRecognizerSupport() können Sie prüfen, ob die Zielplattform unterstützt die Funktionen zur Handschrifterkennung, die Sie verwenden möchten. Im folgenden Beispiel Entwickler:

  • möchte Texte auf Englisch erkennen
  • alternative, weniger wahrscheinliche Vorhersagen erhalten (falls verfügbar)
  • Zugriff auf das Segmentierungsergebnis erhalten, d.h. die erkannten Zeichen, einschließlich der Punkte und Schwimmzüge, aus denen sie bestehen
const { languages, alternatives, segmentationResults } =
  await navigator.queryHandwritingRecognizerSupport({
    languages: ['en'],
    alternatives: true,
    segmentationResult: true,
  });

console.log(languages); // true or false
console.log(alternatives); // true or false
console.log(segmentationResult); // true or false

Die Methode gibt ein Versprechen zurück, das mit einem Ergebnisobjekt aufgelöst wird. Ob der Browser die Funktion unterstützt vom Entwickler angegeben wurde, wird der Wert auf true gesetzt. Andernfalls wird er auf false gesetzt. Anhand dieser Informationen können Sie bestimmte Funktionen in Ihrer Anwendung aktivieren oder deaktivieren passen Sie Ihre Abfrage an und senden Sie eine neue.

Zeichnung starten

Innerhalb Ihrer Anwendung sollten Sie einen Eingabebereich anbieten, in dem Nutzende ihre handschriftlichen Einträge. Aus Leistungsgründen empfiehlt es sich, die Implementierung mithilfe eines Canvas-Objekt. Die genaue Implementierung dieses Teils wird in diesem Artikel nicht behandelt. Sie können sich jedoch die Demo ansehen. um zu sehen, wie das geht.

Wenn Sie eine neue Zeichnung starten möchten, rufen Sie die Methode startDrawing() für die Erkennung auf. Bei dieser Methode wird ein Objekt mit verschiedenen Hinweisen zur Feinabstimmung des Erkennungsalgorithmus. Alle Hinweise sind optional:

  • Art des eingegebenen Textes: Text, E-Mail-Adressen, Zahlen oder ein einzelnes Zeichen (recognitionType)
  • Die Art des Eingabegeräts: Maus, Berührung oder Stift (inputType)
  • Der vorherige Text (textContext)
  • Die Anzahl unwahrscheinlicher alternativer Vorhersagen, die zurückgegeben werden sollten (alternatives)
  • Eine Liste mit Zeichen, die der Nutzer mit hoher Wahrscheinlichkeit eingeben wird (graphemeSet)

Die Handwriting Recognition API eignet sich gut für Zeigerereignisse, die eine abstrakte Schnittstelle, mit der Eingaben von jedem Zeigegerät verarbeitet werden können. Die Argumente des Zeigerereignisses enthalten den verwendeten Zeigertyp. Das bedeutet, dass Sie Zeigerereignisse verwenden können, um den Eingabetyp automatisch. Im folgenden Beispiel wird die Zeichnung zur Handschrifterkennung automatisch wurde beim ersten Auftreten des pointerdown-Ereignisses im Handschriftbereich erstellt. Da die pointerType kann leer sein oder auf einen eigenen Wert festgelegt sein. Ich habe eine Konsistenzprüfung eingeführt, um Vergewissern Sie sich, dass nur unterstützte Werte für den Eingabetyp der Zeichnung eingestellt sind.

let drawing;
let activeStroke;

canvas.addEventListener('pointerdown', (event) => {
  if (!drawing) {
    drawing = recognizer.startDrawing({
      recognitionType: 'text', // email, number, per-character
      inputType: ['mouse', 'touch', 'pen'].find((type) => type === event.pointerType),
      textContext: 'Hello, ',
      alternatives: 2,
      graphemeSet: ['f', 'i', 'z', 'b', 'u'], // for a fizz buzz entry form
    });
  }
  startStroke(event);
});

Kontur hinzufügen

Das Ereignis pointerdown ist auch der richtige Ort, um einen neuen Strich zu beginnen. Erstellen Sie dazu ein neues Instanz von HandwritingStroke. Außerdem sollten Sie die aktuelle Uhrzeit als Bezugspunkt für werden die nachfolgenden Punkte hinzugefügt:

function startStroke(event) {
  activeStroke = {
    stroke: new HandwritingStroke(),
    startTime: Date.now(),
  };
  addPoint(event);
}

Punkt hinzufügen

Nachdem Sie die Kontur erstellt haben, sollten Sie den ersten Punkt direkt hinzufügen. Da Sie weitere ist es sinnvoll, die Punkterstellungslogik in einer separaten Methode zu implementieren. Im Im folgenden Beispiel berechnet die Methode addPoint() die verstrichene Zeit anhand des Referenzzeitstempels. Die zeitlichen Informationen sind optional, können aber die Erkennungsqualität verbessern. Dann werden X und Y-Koordinaten aus dem Zeigerereignis und fügt den Punkt zum aktuellen Strich hinzu.

function addPoint(event) {
  const timeElapsed = Date.now() - activeStroke.startTime;
  activeStroke.stroke.addPoint({
    x: event.offsetX,
    y: event.offsetY,
    t: timeElapsed,
  });
}

Der pointermove-Event-Handler wird aufgerufen, wenn der Mauszeiger über den Bildschirm bewegt wird. Diese Punkte müssen ebenfalls zur Kontur hinzugefügt werden. Das Ereignis kann auch ausgelöst werden, wenn sich der Zeiger nicht in einer "nach unten" z. B. wenn der Cursor über den Bildschirm bewegt wird, ohne die Maus zu drücken Schaltfläche. Der Ereignis-Handler aus dem folgenden Beispiel prüft, ob ein aktiver Strich vorhanden ist, und fügt den einen neuen Punkt hinzu.

canvas.addEventListener('pointermove', (event) => {
  if (activeStroke) {
    addPoint(event);
  }
});

Text erkennen

Wenn der Nutzer den Zeiger wieder anhebt, können Sie die Kontur Ihrer Zeichnung hinzufügen, indem Sie die addStroke()-Methode. Im folgenden Beispiel wird auch activeStroke zurückgesetzt, sodass die pointermove Dem abgeschlossenen Strich werden keine Punkte hinzugefügt.

Als Nächstes muss die Eingabe des Nutzers erkannt werden. Rufen Sie dazu die Methode getPrediction() auf der zeichnen können. Die Erkennung dauert in der Regel weniger als ein paar Hundert Millisekunden, sodass Sie Vorhersagen zu treffen. Im folgenden Beispiel wird nach jedem abgeschlossenen Strich eine neue Vorhersage ausgeführt.

canvas.addEventListener('pointerup', async (event) => {
  drawing.addStroke(activeStroke.stroke);
  activeStroke = null;

  const [mostLikelyPrediction, ...lessLikelyAlternatives] = await drawing.getPrediction();
  if (mostLikelyPrediction) {
    console.log(mostLikelyPrediction.text);
  }
  lessLikelyAlternatives?.forEach((alternative) => console.log(alternative.text));
});

Diese Methode gibt ein Versprechen zurück, das mit einem Array von Vorhersagen aufgelöst wird, das nach ihrer Wahrscheinlichkeit. Die Anzahl der Elemente hängt vom Wert ab, den Sie an den alternatives-Hinweis übergeben haben. Ich könnte dieses Array verwendet werden, um dem Nutzer eine Auswahl an möglichen Übereinstimmungen zu präsentieren und ihn eine Auswahl Option. Alternativ können Sie einfach die höchstwahrscheinliche Vorhersage verwenden. Dies ist das, was ich in der Beispiel.

Das Vorhersageobjekt enthält den erkannten Text und ein optionales Segmentierungsergebnis, das ich die wir im folgenden Abschnitt besprechen.

Detaillierte Statistiken mit Segmentierungsergebnissen

Falls die Zielplattform dies unterstützt, kann das Vorhersageobjekt auch ein Segmentierungsergebnis enthalten. Dies ist ein Array, das das gesamte erkannte Handschriftsegment enthält, eine Kombination aus nutzeridentifizierbares Zeichen (grapheme) und seine Position im erkannten Text (beginIndex, endIndex) sowie die Striche und Punkte, mit denen sie erstellt wurde.

if (mostLikelyPrediction.segmentationResult) {
  mostLikelyPrediction.segmentationResult.forEach(
    ({ grapheme, beginIndex, endIndex, drawingSegments }) => {
      console.log(grapheme, beginIndex, endIndex);
      drawingSegments.forEach(({ strokeIndex, beginPointIndex, endPointIndex }) => {
        console.log(strokeIndex, beginPointIndex, endPointIndex);
      });
    },
  );
}

Anhand dieser Informationen können Sie die auf dem Canvas erkannten Graphen wiederfinden.

Um jedes erkannte Graphem werden Felder gezeichnet

Vollständige Erkennung

Nach Abschluss der Erkennung können Sie Ressourcen freigeben, indem Sie die Methode clear() auf der HandwritingDrawing und der finish()-Methode für HandwritingRecognizer:

drawing.clear();
recognizer.finish();

Demo

Mit der Webkomponente „<handwriting-textarea>“ wird ein fortlaufend verbessert, Bearbeitungssteuerung mit Handschriftfunktion Anerkennung. Wenn Sie auf die Schaltfläche unten rechts im Bearbeitungssteuerelement klicken, aktivieren Sie im Zeichenmodus. Wenn Sie die Zeichnung fertiggestellt haben, startet die Web-Komponente automatisch und fügen Sie den erkannten Text wieder zum Bearbeitungssteuerelement hinzu. Wenn die Handschrifterkennung API wird überhaupt nicht unterstützt oder die Plattform unterstützt die angeforderten Funktionen nicht, Schaltfläche „Bearbeiten“ werden ausgeblendet. Die grundlegenden Bearbeitungssteuerelemente können jedoch weiterhin als <textarea> verwendet werden.

Die Webkomponente bietet Eigenschaften und Attribute, um das Erkennungsverhalten der außerhalb, darunter languages und recognitiontype. Sie können den Inhalt des Steuerelements über die Attribut value:

<handwriting-textarea languages="en" recognitiontype="text" value="Hello"></handwriting-textarea>

Wenn Sie über Änderungen am Wert informiert werden möchten, können Sie auf das input-Ereignis warten.

Sie können die Komponente mithilfe dieser Demo zu Glitch ausprobieren. Sie sollten sich auch die Quellcode. Um das Steuerelement in Ihrem erhalten Sie sie von npm.

Sicherheit und Berechtigungen

Das Chromium-Team entwickelte und implementierte die Handwriting Recognition API nach den Grundprinzipien. wie unter Zugriff auf leistungsstarke Webplattform-Funktionen steuern beschrieben, einschließlich Transparenz und Ergonomie.

Nutzersteuerung

Die Handschrifterkennungs-API kann vom Nutzer nicht deaktiviert werden. Sie ist nur für Websites verfügbar. werden über HTTPS bereitgestellt und können nur vom Browser auf oberster Ebene aufgerufen werden.

Transparenz

Es wird nicht angezeigt, ob die Handschrifterkennung aktiv ist. Um die Verwendung von Fingerprinting zu verhindern, Gegenmaßnahmen implementiert, z. B. dem Nutzer eine Berechtigungsaufforderung anzeigt, wenn er erkennt, möglicher Missbrauch.

Berechtigungstreue

Die Handwriting Recognition API zeigt derzeit keine Berechtigungsaufforderung an. Daher ist die Berechtigung muss nicht beibehalten werden.

Feedback

Das Chromium-Team möchte mehr über Ihre Erfahrungen mit der Handwriting Recognition API wissen.

Informationen zum API-Design

Funktioniert die API nicht wie erwartet? Oder fehlen Methoden, oder Eigenschaften, die Sie für die Umsetzung Ihrer Idee benötigen? Fragen oder Kommentare zur Sicherheit haben Modell? Reichen Sie ein Spezifikationsproblem im entsprechenden GitHub-Repository ein oder fügen Sie Ihre Gedanken zu einem Problem zu beheben.

Problem mit der Implementierung melden

Hast du einen Fehler bei der Implementierung von Chromium gefunden? Oder weicht die Implementierung von der Spezifikation ab? Melde einen Fehler unter new.crbug.com. Geben Sie so viele Details wie möglich an, Anweisungen zum Reproduzieren und gib Blink>Handwriting in das Feld Komponenten ein. Glitch eignet sich hervorragend, um schnelle und einfache Reproduktionen zu teilen.

Unterstützung für die API anzeigen

Möchten Sie die Handwriting Recognition API verwenden? Dein öffentlicher Support hilft dem Chromium-Team Funktionen priorisieren und anderen Browseranbietern zeigen, wie wichtig es für ihre Unterstützung ist.

Im WICG Discourse-Thread können Sie uns mitteilen, wie Sie den Dienst verwenden möchten. Tweet senden an @ChromiumDev mit dem Hashtag #HandwritingRecognition und teilen Sie uns mit, wo und wie Sie sie nutzen.

Danksagungen

Dieser Artikel wurde von Joe Medley, Honglin Yu und Jiewei Qian gelesen. Hero-Image von Samir Bouaked auf Unsplash (Unsplash).