El Yazısı Tanıma API'si, el yazısı girişindeki metni yazıldığı sırada tanımanıza olanak tanır.
El Yazısı Tanıma API'si nedir?
El Yazısı Tanıma API'si, kullanıcılarınızın el yazısını (mürekkep) metne dönüştürmenize olanak tanır. Bazı işletim sistemleri bu tür API'leri uzun süredir içeriyordu. Bu yeni özellik sayesinde web uygulamalarınız da nihayet bu işlevi kullanabilir. Dönüşüm doğrudan kullanıcının cihazında gerçekleşir ve hiçbir üçüncü taraf kitaplığı veya hizmeti eklenmeden çevrimdışı modda bile çalışır.
Bu API, "online" veya neredeyse gerçek zamanlı tanıma olarak adlandırılan yöntemi uygular. Bu, kullanıcı çizerken tek tek vuruşları yakalayıp analiz ederek el yazısı girişinin tanındığı anlamına gelir. Yalnızca nihai ürünün bilinen Optik Karakter Tanıma (OCR) gibi "çevrimdışı" işlemlerin aksine, çevrimiçi algoritmalar, mürekkebin tek tek vuruşlarının zamansal sırası ve basıncı gibi ek sinyaller sayesinde daha yüksek düzeyde doğruluk sağlayabilir.
El Yazısı Tanıma API'si için önerilen kullanım alanları
Örnek kullanımlar:
- Kullanıcıların el yazısıyla notlar alıp bunları metne dönüştürmek istediği not alma uygulamaları.
- Kullanıcıların zaman kısıtlamaları nedeniyle kalem veya parmak girişi kullanabileceği Formlar uygulamaları.
- Kelime bulmaca, asma adam veya sudoku gibi harf ya da sayı doldurmayı gerektiren oyunlar.
Mevcut durum
El Yazısı Tanıma API'si (Chromium 99) sürümünden itibaren kullanılabilir.
El Yazısı Tanıma API'sini kullanma
Özellik algılama
Gezgin nesnesinde createHandwritingRecognizer()
yönteminin varlığını kontrol ederek tarayıcı desteğini algılayın:
if ('createHandwritingRecognizer' in navigator) {
// 🎉 The Handwriting Recognition API is supported!
}
Temel kavramlar
El Yazısı Tanıma API'si, giriş yönteminden (fare, dokunma, kalem) bağımsız olarak el yazısı girişini metne dönüştürür. API'nin dört ana öğesi vardır:
- Nokta, işaretçinin belirli bir zamandaki yerini temsil eder.
- Çizgi, bir veya daha fazla noktadan oluşur. Bir çizginin kaydı, kullanıcı işaretçiyi aşağı indirdiğinde (ör. birincil fare düğmesini tıkladığında veya ekrana kalemiyle ya da parmağıyla dokunduğunda) başlar ve işaretçiyi tekrar yukarı kaldırdığında sona erer.
- Çizim, bir veya daha fazla çizgiden oluşur. Gerçek tanıma işlemi bu düzeyde gerçekleşir.
- Tanıyıcı, beklenen giriş diliyle yapılandırılır. Tanımlayıcı yapılandırması uygulanmış bir çizim örneği oluşturmak için kullanılır.
Bu kavramlar, kısa süre içinde ele alacağım belirli arayüzler ve sözlükler olarak uygulanır.
Tanımlayıcı oluşturma
El yazısı girişindeki metni tanımak için navigator.createHandwritingRecognizer()
'u çağırıp ona kısıtlamalar göndererek bir HandwritingRecognizer
örneği elde etmeniz gerekir. Kısıtlamalar, kullanılacak el yazısı tanıma modelini belirler. Şu anda, tercih sırasına göre bir dil listesi belirtebilirsiniz:
const recognizer = await navigator.createHandwritingRecognizer({
languages: ['en'],
});
Tarayıcı isteğinizi yerine getirebiliyorsa yöntem, HandwritingRecognizer
örneğiyle çözülen bir promise döndürür. Aksi takdirde, söz konusu vaat bir hatayla reddedilir ve el yazısı tanıma kullanılamaz. Bu nedenle, önce tanımlayıcının belirli tanıma özellikleri için destek sunup sunmadığını sorgulamak isteyebilirsiniz.
Tanımlayıcı desteğini sorgulayın
navigator.queryHandwritingRecognizerSupport()
işlevini çağırarak hedef platformun, kullanmak istediğiniz el yazısı tanıma özelliklerini destekleyip desteklemediğini kontrol edebilirsiniz. Aşağıdaki örnekte geliştirici:
- İngilizce metinleri algılamak istiyor
- Mümkün olduğunda alternatif, daha az olasılık içeren tahminler alın
- Segmentasyon sonucuna (ör. onları oluşturan noktalar ve çizgiler dahil olmak üzere tanınan karakterler) erişme
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
Yöntem, bir sonuç nesnesi ile çözülen bir promise döndürür. Tarayıcı, geliştirici tarafından belirtilen özelliği destekliyorsa özelliğin değeri true
olarak ayarlanır. Aksi takdirde false
olarak ayarlanır.
Bu bilgileri, uygulamanızdaki belirli özellikleri etkinleştirmek veya devre dışı bırakmak ya da sorgunuzu ayarlamak ve yeni bir sorgu göndermek için kullanabilirsiniz.
Çizim başlatma
Uygulamanızda, kullanıcının el yazısıyla giriş yapabileceği bir giriş alanı sunmanız gerekir. Performans nedeniyle bunu bir tuval nesnesi yardımıyla uygulamanız önerilir. Bu bölümün tam olarak uygulanması bu makalenin kapsamı dışındadır ancak nasıl yapılabileceğini görmek için demo bölümüne göz atabilirsiniz.
Yeni bir çizim başlatmak için tanımlayıcıdaki startDrawing()
yöntemini çağırın. Bu yöntem, tanıma algoritmasında ince ayar yapmak için farklı ipuçları içeren bir nesne alır. Tüm ipuçları isteğe bağlıdır:
- Girilecek metin türü: metin, e-posta adresleri, sayılar veya tek bir karakter (
recognitionType
) - Giriş cihazının türü: fare, dokunma veya kalem girişi (
inputType
) - Önceki metin (
textContext
) - Döndürülmesi gereken daha az olası alternatif tahminlerin sayısı (
alternatives
) - Kullanıcının büyük olasılıkla gireceği, kullanıcı tarafından tanımlanabilen karakterlerin ("grafemler") listesi (
graphemeSet
)
El Yazısı Tanıma API'si, herhangi bir işaretçi cihazdan giriş almak için soyut bir arayüz sağlayan İşaretçi Etkinlikleri ile iyi çalışır. İşaretçi etkinliği bağımsız değişkenleri, kullanılan işaretçi türünü içerir. Bu, giriş türünü otomatik olarak belirlemek için işaretçi etkinliklerini kullanabileceğiniz anlamına gelir. Aşağıdaki örnekte, el yazısı tanıma için çizim, el yazısı alanında bir pointerdown
etkinliğinin ilk oluşumunda otomatik olarak oluşturulur. pointerType
boş olabilir veya özel bir değere ayarlanmış olabilir. Bu nedenle, çizimin giriş türü için yalnızca desteklenen değerlerin ayarlandığından emin olmak amacıyla bir tutarlılık kontrolü ekledim.
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 ekleme
pointerdown
etkinliği, yeni bir vuruş başlatmak için de doğru yerdir. Bunun için yeni bir HandwritingStroke
örneği oluşturun. Ayrıca, mevcut zamanı, ona eklenen sonraki noktalar için referans noktası olarak saklamanız gerekir:
function startStroke(event) {
activeStroke = {
stroke: new HandwritingStroke(),
startTime: Date.now(),
};
addPoint(event);
}
Nokta ekleyin
Kalın çizgiyi oluşturduktan sonra doğrudan ilk noktayı eklemeniz gerekir. Daha sonra daha fazla puan ekleyeceğiniz için puan oluşturma mantığını ayrı bir yöntemde uygulamak mantıklı olacaktır. Aşağıdaki örnekte addPoint()
yöntemi, referans zaman damgasından itibaren geçen süreyi hesaplar.
Zamansal bilgiler isteğe bağlıdır ancak tanıma kalitesini iyileştirebilir. Ardından, işaretçi etkinliğindeki X ve Y koordinatlarını okur ve noktayı mevcut çizgiye ekler.
function addPoint(event) {
const timeElapsed = Date.now() - activeStroke.startTime;
activeStroke.stroke.addPoint({
x: event.offsetX,
y: event.offsetY,
t: timeElapsed,
});
}
İşaretçi ekranda hareket ettirildiğinde pointermove
etkinlik işleyici çağrılır. Bu noktaların çizgiye de eklenmesi gerekir. İşaretçi "aşağı" durumda değilse de (ör. fare düğmesine basmadan imleci ekranda hareket ettirirken) etkinlik tetiklenebilir. Aşağıdaki örnekteki etkinlik işleyici, etkin bir çizgi olup olmadığını kontrol eder ve yeni noktayı buna ekler.
canvas.addEventListener('pointermove', (event) => {
if (activeStroke) {
addPoint(event);
}
});
Metni tanıma
Kullanıcı işaretçiyi tekrar kaldırdığında, addStroke()
yöntemini çağırarak çizgiyi çiziminize ekleyebilirsiniz. Aşağıdaki örnekte activeStroke
da sıfırlanır. Böylece pointermove
işleyicisi, tamamlanan çizgiye nokta eklemez.
Ardından, çizimde getPrediction()
yöntemini çağırarak kullanıcının girişini tanıma zamanı gelmiştir. Tanımlama işlemi genellikle birkaç yüz milisaniyeden kısa sürer. Bu nedenle, gerekirse tahminleri tekrar tekrar çalıştırabilirsiniz. Aşağıdaki örnekte, her tamamlanan vuruştan sonra yeni bir tahmin çalıştırılır.
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));
});
Bu yöntem, olasılıklarına göre sıralanmış bir tahmin dizisiyle çözülen bir promise döndürür. Öğe sayısı, alternatives
ipucuna ilettiğiniz değere bağlıdır. Kullanıcıya olası eşleşmeler arasından seçim yapması için bu diziyi kullanabilir ve bir seçenek seçmesini isteyebilirsiniz. Alternatif olarak, en olası tahmini kullanabilirsiniz. Örnekte bunu yapıyorum.
Tahmin nesnesi, tanınan metni ve isteğe bağlı bir segmentasyon sonucunu içerir. Bu konuyu aşağıdaki bölümde ele alacağım.
Segmentasyon sonuçlarıyla ayrıntılı analizler
Hedef platform tarafından destekleniyorsa tahmin nesnesi bir segmentasyon sonucu da içerebilir.
Bu, tanınan tüm el yazısı segmentini içeren bir dizidir. Tanınan kullanıcı tarafından tanımlanabilir karakterin (grapheme
) tanınan metindeki konumuyla (beginIndex
, endIndex
) ve onu oluşturan vuruş ve noktalarla birlikte bir kombinasyondur.
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);
});
},
);
}
Bu bilgileri kullanarak, tuvalde tanınan grafemleri tekrar bulabilirsiniz.
Tam tanıma
Tanımlama işlemi tamamlandıktan sonra HandwritingDrawing
üzerinde clear()
yöntemini ve HandwritingRecognizer
üzerinde finish()
yöntemini çağırarak kaynakları serbest bırakabilirsiniz:
drawing.clear();
recognizer.finish();
Demo
<handwriting-textarea>
web bileşeni, el yazısı tanıma özelliğine sahip kademeli olarak geliştirilmiş bir düzenleme denetimi uygular. Düzenleme denetiminin sağ alt köşesindeki düğmeyi tıklayarak çizim modunu etkinleştirebilirsiniz. Çizimi tamamladığınızda web bileşeni otomatik olarak tanıma işlemini başlatır ve tanınan metni düzenleme denetimine geri ekler. El yazısı tanıma API'si hiç desteklenmiyorsa veya platform istenen özellikleri desteklemiyorsa düzenleme düğmesi gizlenir. Ancak temel düzenleme denetimi <textarea>
olarak kullanılabilir durumda kalır.
Web bileşeni, languages
ve recognitiontype
dahil olmak üzere tanıma davranışını dışarıdan tanımlamak için özellikler ve özellikler sunar. Kontrolün içeriğini value
özelliği aracılığıyla ayarlayabilirsiniz:
<handwriting-textarea languages="en" recognitiontype="text" value="Hello"></handwriting-textarea>
Değerdeki değişiklikler hakkında bilgi edinmek için input
etkinliğini dinleyebilirsiniz.
Bileşeni Glitch'teki bu demoyu kullanarak deneyebilirsiniz. Ayrıca kaynak koda da göz atın. Kontrolü uygulamanızda kullanmak için npm'den edinin.
Güvenlik ve izinler
Chromium ekibi, kullanıcı kontrolü, şeffaflık ve ergonomi gibi Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme başlıklı makalede tanımlanan temel ilkeleri kullanarak El Yazısı Tanıma API'sini tasarlayıp uyguladı.
Kullanıcı denetimi
El yazısı tanıma API'si kullanıcı tarafından devre dışı bırakılamaz. Yalnızca HTTPS üzerinden yayınlanan web sitelerinde kullanılabilir ve yalnızca üst düzey tarama bağlamından çağrılabilir.
Şeffaflık
El yazısı tanıma özelliğinin etkin olup olmadığı gösterilmez. Tarayıcı, parmak izi oluşturmayı önlemek için olası bir kötüye kullanım algıladığında kullanıcıya izin istemi göstermek gibi karşı önlemler uygular.
İzin kalıcılığı
El Yazısı Tanıma API'si şu anda herhangi bir izin istemi göstermiyor. Bu nedenle, iznin herhangi bir şekilde devam ettirilmesi gerekmez.
Geri bildirim
Chromium ekibi, El Yazısı Tanıma API'si ile ilgili deneyimlerinizi öğrenmek istiyor.
API tasarımı hakkında bilgi verin
API ile ilgili olarak beklediğiniz gibi çalışmayan bir şey var mı? Yoksa fikrinizi uygulamak için ihtiyaç duyduğunuz yöntemler veya özellikler eksik mi? Güvenlik modeliyle ilgili sorunuz veya yorumunuz mu var? İlgili GitHub deposunda spesifikasyon sorunu oluşturun veya mevcut bir soruna düşüncelerinizi ekleyin.
Uygulamayla ilgili sorunları bildirme
Chromium'un uygulamasında bir hata mı buldunuz? Yoksa uygulama, spesifikasyondan farklı mı?
new.crbug.com adresinden hata kaydı oluşturun. Mümkün olduğunca fazla ayrıntı ekleyin, hatayı yeniden oluşturmayla ilgili basit talimatlar verin ve Bileşenler kutusuna Blink>Handwriting
yazın.
Glitch, hızlı ve kolay yeniden oluşturma işlemlerini paylaşmak için idealdir.
API'yi destekleme
El yazısı tanıma API'sini kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chromium ekibinin özelliklere öncelik vermesine yardımcı olur ve diğer tarayıcı tedarikçi firmalarına bu özellikleri desteklemenin ne kadar önemli olduğunu gösterir.
WICG Discourse mesaj dizisinde bu özelliği nasıl kullanmayı planladığınızı paylaşın. #HandwritingRecognition
hashtag'ini kullanarak @ChromiumDev hesabına tweet gönderin ve bu özelliği nerede ve nasıl kullandığınızı bize bildirin.
Yararlı Bağlantılar
- Açıklayıcı
- Özellik taslağı
- GitHub deposu
- ChromeStatus
- Chromium hatası
- TAG incelemesi
- Prototip oluşturma amacı
- WebKit-Dev mesaj dizisi
- Mozilla'nın standartlar konusundaki konumu
Teşekkür ederiz
Bu doküman Joe Medley, Honglin Yu ve Jiewei Qian tarafından incelenmiştir.