El Yazısı Tanıma API'si, el yazısı girişlerinden gelen metinleri daha anında 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, "çevrimiçi" veya neredeyse gerçek zamanlı tanıma 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 son ürünün bilindiği Optik Karakter Tanıma (OCR) gibi "çevrimdışı" prosedürlerin aksine, çevrimiçi algoritmalar, tek tek mürekkep darbelerinin zamansal sırası ve basıncı gibi ek sinyaller nedeniyle daha yüksek doğruluk düzeyi sağlayabilir.
El Yazısı Tanıma API'si için önerilen kullanım alanları
Örnek kullanımlar aşağıdakileri içerir:
- 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 parmakla giriş yapabileceği form uygulamaları.
- Bulmaca, hangman veya sudoku gibi harf veya rakam girilmesini 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
Gezinme nesnesinde createHandwritingRecognizer()
yönteminin olup olmadığını kontrol ederek tarayıcı desteğini tespit edin:
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 elle yazılmış girişleri metne dönüştürür. API'nin dört ana öğesi vardır:
- Nokta, işaretçinin belirli bir zamandaki yerini gösterir.
- Ç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. Asıl tanıma işlemi bu düzeyde gerçekleşir.
- Tanımlayı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 tercihinize 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 taahhüt bir hatayla reddedilir ve el yazısı tanıma kullanılamaz. Bu nedenle, ilk olarak tanıyıcının belirli tanıma özellikleri için desteğini 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ştiricinin belirttiği özelliği destekliyorsa 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ı artırmak için bunu bir kanvas 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ının kimliğini tanımlayabilecek karakterlerin ("grafikler") 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ş olabileceği veya özel bir değere ayarlanmış olabileceğinden, çizimin giriş türü için yalnızca desteklenen değerlerin ayarlandığından emin olmak amacıyla tutarlılık kontrolü başlattım.
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 çizgi başlatmak için de doğru yerdir. Bunu yapmak 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, geçen süreyi referans zaman damgasından 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,
});
}
pointermove
etkinlik işleyicisi, işaretçi ekran boyunca hareket ettirildiğinde ç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 örnekte yer alan etkinlik işleyici, etkin bir fırçanın olup olmadığını kontrol eder ve yeni noktayı buna ekler.
canvas.addEventListener('pointermove', (event) => {
if (activeStroke) {
addPoint(event);
}
});
Metni tanı
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 puan eklemez.
Ardından, çizimde getPrediction()
yöntemini çağırarak kullanıcının girişini tanıma zamanı gelmiştir. Tanıma 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. Bu diziyi, kullanıcıya olası eşleşmeler sunmak ve bir seçenek belirlemesini sağlamak için kullanabilirsiniz. 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 sonuçları aşağıdaki bölümde ele alacağız.
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 tanıma işlemini otomatik olarak 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 bir spesifikasyon sorunu bildirin 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 özellikleri önceliklendirmesine yardımcı olur ve diğer tarayıcı tedarikçilerine bunları desteklemenin ne kadar kritik olduğunu gösterir.
Bu özelliği nasıl kullanmayı planladığınızı WICG Discourse ileti dizisinde 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 standartları konumu
Teşekkür
Bu doküman Joe Medley, Honglin Yu ve Jiewei Qian tarafından incelenmiştir.