API Nhận dạng chữ viết tay cho phép bạn nhận dạng văn bản từ dữ liệu đầu vào viết tay ngay khi dữ liệu đó xuất hiện.
Handwriting Recognition API là gì?
API Nhận dạng chữ viết tay cho phép bạn chuyển đổi chữ viết tay (mực) của người dùng thành văn bản. Một số hệ điều hành đã có sẵn các API như vậy từ lâu và nhờ tính năng mới này, các ứng dụng web của bạn cuối cùng cũng có thể sử dụng chức năng này. Lượt chuyển đổi diễn ra trực tiếp trên thiết bị của người dùng, hoạt động ngay cả ở chế độ ngoại tuyến mà không cần thêm bất kỳ thư viện hoặc dịch vụ nào của bên thứ ba.
API này triển khai cái gọi là tính năng nhận dạng "trực tuyến" hoặc gần như theo thời gian thực. Điều này có nghĩa là dữ liệu đầu vào viết tay được nhận dạng trong khi người dùng vẽ bằng cách ghi lại và phân tích các nét vẽ riêng lẻ. Ngược lại với các quy trình "ngoại tuyến" như Nhận dạng ký tự quang học (OCR), trong đó chỉ có sản phẩm cuối cùng được biết, các thuật toán trực tuyến có thể cung cấp độ chính xác cao hơn do các tín hiệu bổ sung như chuỗi thời gian và áp lực của từng nét mực riêng lẻ.
Các trường hợp sử dụng được đề xuất cho Handwriting Recognition API
Ví dụ về cách sử dụng:
- Các ứng dụng ghi chú mà người dùng muốn ghi lại ghi chú viết tay và dịch ghi chú đó thành văn bản.
- Các ứng dụng biểu mẫu mà người dùng có thể sử dụng bút cảm ứng hoặc ngón tay để nhập dữ liệu do hạn chế về thời gian.
- Những trò chơi yêu cầu điền chữ cái hoặc số, chẳng hạn như trò chơi ô chữ, trò chơi treo cổ hoặc trò chơi sudoku.
Trạng thái hiện tại
Handwriting Recognition API (API Nhận dạng chữ viết tay) có trong (Chromium 99).
Cách sử dụng Handwriting Recognition API
Phát hiện đối tượng
Phát hiện khả năng hỗ trợ của trình duyệt bằng cách kiểm tra sự tồn tại của phương thức createHandwritingRecognizer() trên đối tượng trình điều hướng:
if ('createHandwritingRecognizer' in navigator) {
// 🎉 The Handwriting Recognition API is supported!
}
Các khái niệm cốt lõi
Handwriting Recognition API (API Nhận dạng chữ viết tay) chuyển đổi dữ liệu đầu vào viết tay thành văn bản, bất kể phương thức nhập (chuột, thao tác chạm, bút cảm ứng). API này có 4 thực thể chính:
- Điểm biểu thị vị trí của con trỏ tại một thời điểm cụ thể.
- Một nét vẽ bao gồm một hoặc nhiều điểm. Quá trình ghi lại một nét bắt đầu khi người dùng đặt con trỏ xuống (tức là nhấp vào nút chuột chính hoặc chạm vào màn hình bằng bút cảm ứng hoặc ngón tay) và kết thúc khi họ nhấc con trỏ lên.
- Một hình vẽ bao gồm một hoặc nhiều nét vẽ. Hoạt động nhận dạng thực tế diễn ra ở cấp độ này.
- Trình nhận dạng được định cấu hình bằng ngôn ngữ nhập dự kiến. Phương thức này dùng để tạo một phiên bản bản vẽ có cấu hình trình nhận dạng được áp dụng.
Những khái niệm này được triển khai dưới dạng các giao diện và từ điển cụ thể mà tôi sẽ đề cập ngay sau đây.

Tạo một trình nhận dạng
Để nhận dạng văn bản từ dữ liệu đầu vào viết tay, bạn cần lấy một thực thể của HandwritingRecognizer bằng cách gọi navigator.createHandwritingRecognizer() và truyền các ràng buộc đến thực thể đó. Các quy tắc ràng buộc xác định mô hình nhận dạng chữ viết tay cần được sử dụng. Hiện tại, bạn có thể chỉ định một danh sách ngôn ngữ theo thứ tự ưu tiên:
const recognizer = await navigator.createHandwritingRecognizer({
languages: ['en'],
});
Phương thức này trả về một lời hứa phân giải bằng một thực thể của HandwritingRecognizer khi trình duyệt có thể thực hiện yêu cầu của bạn. Nếu không, phương thức này sẽ từ chối lời hứa bằng một lỗi và tính năng nhận dạng chữ viết tay sẽ không hoạt động. Vì lý do này, trước tiên, bạn nên truy vấn khả năng hỗ trợ của trình nhận dạng đối với các tính năng nhận dạng cụ thể.
Truy vấn hỗ trợ của trình nhận dạng
Bằng cách gọi navigator.queryHandwritingRecognizer(), bạn có thể kiểm tra xem nền tảng mục tiêu có hỗ trợ các tính năng nhận dạng chữ viết tay mà bạn dự định sử dụng hay không. Phương thức này lấy cùng một đối tượng ràng buộc như phương thức navigator.createHandwritingRecognizer(), chứa danh sách các ngôn ngữ được yêu cầu. Phương thức này trả về một lời hứa phân giải bằng một đối tượng kết quả nếu tìm thấy một trình nhận dạng tương thích. Nếu không, lời hứa sẽ phân giải thành null.
Trong ví dụ sau, nhà phát triển:
- muốn phát hiện văn bản bằng tiếng Anh
- nhận các dự đoán thay thế, ít có khả năng xảy ra hơn (nếu có)
- truy cập vào kết quả phân đoạn, tức là các ký tự được nhận dạng, bao gồm cả các điểm và nét tạo nên các ký tự đó
const result =
await navigator.queryHandwritingRecognizerSupport({
languages: ['en']
});
console.log(result?.textAlternatives); // true if alternatives are supported
console.log(result?.textSegmentation); // true if segmentation is supported
Nếu trình duyệt hỗ trợ tính năng mà nhà phát triển cần, thì giá trị của tính năng đó sẽ được đặt thành true trong đối tượng kết quả. Nếu không, giá trị này sẽ được đặt thành false.
Bạn có thể sử dụng thông tin này để bật hoặc tắt một số tính năng trong ứng dụng của mình hoặc gửi một cụm từ tìm kiếm mới cho một nhóm ngôn ngữ khác.
Bắt đầu vẽ
Trong ứng dụng của mình, bạn nên cung cấp một vùng nhập dữ liệu để người dùng nhập dữ liệu viết tay. Vì lý do hiệu suất, bạn nên triển khai việc này bằng sự trợ giúp của đối tượng canvas. Việc triển khai chính xác phần này nằm ngoài phạm vi của bài viết này, nhưng bạn có thể tham khảo bản minh hoạ để xem cách thực hiện.
Để bắt đầu vẽ một hình mới, hãy gọi phương thức startDrawing() trên trình nhận dạng. Phương thức này lấy một đối tượng chứa nhiều gợi ý để tinh chỉnh thuật toán nhận dạng. Bạn không bắt buộc phải cung cấp tất cả các gợi ý:
- Loại văn bản đang được nhập: văn bản, địa chỉ email, số hoặc một ký tự riêng lẻ (
recognitionType) - Loại thiết bị đầu vào: chuột, thao tác chạm hoặc bút cảm ứng (
inputType) - Văn bản trước đó (
textContext) - Số lượng dự đoán thay thế ít có khả năng xảy ra cần được trả về (
alternatives) - Danh sách các ký tự mà người dùng có thể nhận dạng ("đơn vị chữ viết") mà người dùng có nhiều khả năng sẽ nhập (
graphemeSet)
Handwriting Recognition API hoạt động tốt với Pointer Events (Sự kiện con trỏ). API này cung cấp một giao diện trừu tượng để sử dụng dữ liệu đầu vào từ mọi thiết bị trỏ. Các đối số sự kiện con trỏ chứa loại con trỏ đang được sử dụng. Điều này có nghĩa là bạn có thể sử dụng các sự kiện con trỏ để tự động xác định loại dữ liệu đầu vào. Trong ví dụ sau, bản vẽ cho tính năng nhận dạng chữ viết tay sẽ tự động được tạo khi sự kiện pointerdown xảy ra lần đầu tiên trên vùng chữ viết tay. Vì pointerType có thể trống hoặc được đặt thành một giá trị độc quyền, nên tôi đã giới thiệu một quy trình kiểm tra tính nhất quán để đảm bảo chỉ các giá trị được hỗ trợ mới được đặt cho loại đầu vào của bản vẽ.
let drawing;
let activeStroke;
canvas.addEventListener('pointerdown', (event) => {
if (!drawing) {
drawing = recognizer.startDrawing({
recognitionType: 'text', // email, number, per-character
inputType: ['mouse', 'touch', 'stylus'].find((type) => type === event.pointerType),
textContext: 'Hello, ',
alternatives: 2,
graphemeSet: ['f', 'i',