El Yazısı Tanıma API'si, elle yazılmış girişlerdeki metinleri okumanıza olanak tanır.
El Yazısı Tanıma API'sı nedir?
El Yazısı Tanıma API'si, kullanıcılarınızın el yazısını (mürekkebi) metne dönüştürmenizi sağlar. Bazı işletim sistemleri bu tür API'leri uzun süredir içermektedir ve bu yeni özellikle web uygulamalarınız nihayetinde bu işlevi kullanabilir. Dönüştürme işlemi doğrudan kullanıcının cihazında gerçekleşir. Çevrimdışı modda bile çalışır. Bu işlemlerin tamamında herhangi bir üçüncü taraf kitaplığı veya hizmeti eklenmesi gerekmez.
Bu API, "çevrimiçi" veya neredeyse gerçek zamanlı tanıma uygular. Bu, kullanıcı tek vuruşları yakalayıp analiz ederek çizerken el yazısı girişinin tanınacağı anlamına gelir. Yalnızca son ürünün bilindiği Optik Karakter Tanıma (OCR) gibi "çevrimdışı" prosedürlerin aksine çevrimiçi algoritmalar, zamansal sıralama ve mürekkep darbelerinin basıncı gibi ek sinyaller sayesinde daha yüksek bir doğruluk seviyesi sağlayabilir.
El Yazısı Tanıma API'si için önerilen kullanım alanları
Örnek kullanımlar şunları içerir:
- Kullanıcıların elle yazılmış notları yakalayıp metne çevirmesini istedikleri not alma uygulamaları.
- Kullanıcıların zaman kısıtlamaları nedeniyle kalem veya parmakla giriş kullanabildiği form uygulamaları.
- Harflerin veya sayıların girilmesini gerektiren oyunlar (ör. kare bulmaca, hangman veya sudoku).
Mevcut durum
El Yazısı Tanıma API'sine (Chromium 99) ulaşabilirsiniz.
El Yazısı Recognition API'yi kullanma
Özellik algılama
Gezgin nesnesinde createHandwritingRecognizer()
yönteminin mevcut 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şi metne dönüştürür. API'nin dört ana varlığı vardır:
- Nokta, işaretçinin belirli bir zamanda nerede olduğunu gösterir.
- Fırça bir veya daha fazla noktadan oluşur. Çizginin kaydı, kullanıcı işaretçiyi aşağı bıraktığında (ör. birincil fare düğmesini tıkladığında ya da kalemi veya parmağıyla ekrana dokunduğunda) başlar ve işaretçiyi tekrar yukarıya taşıdığında sona erer.
- Çizim, bir veya daha fazla çizgiden oluşur. Gerçek tanıma bu düzeyde gerçekleşir.
- Tanımlayıcı, beklenen giriş diliyle yapılandırılmıştır. Tanımlayıcı yapılandırmasının uygulandığı bir çizim örneği oluşturmak için kullanılır.
Bu kavramlar, belirli arayüzler ve sözlükler olarak uygulanır. Bunlara birazdan değineceğim.
Tanıyıcı oluşturma
Elle yazılmış girişlerdeki metinleri tanımak için navigator.createHandwritingRecognizer()
yöntemini çağırıp kısıtlamaları ona ileterek HandwritingRecognizer
örneği almanız gerekir. Kısıtlamalar, kullanılması gereken 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'],
});
Yöntem, tarayıcı isteğinizi yerine getirebildiğinde HandwritingRecognizer
örneğiyle çözümlenme vaadi döndürür. Aksi takdirde sözü bir hatayla reddeder ve el yazısı tanıma özelliği kullanılamaz. Bu nedenle, ilk olarak belirli tanıma özellikleri için tanıyıcının desteğini sorgulamak isteyebilirsiniz.
Tanıyıcı desteği sorgulama
navigator.queryHandwritingRecognizerSupport()
numaralı telefonu arayarak hedef platformun, kullanmayı düşündüğünüz el yazısı tanıma özelliklerini destekleyip desteklemediğini kontrol edebilirsiniz. Aşağıdaki örnekte geliştirici:
- İngilizce metinleri algılamak istiyor
- mevcut olduğunda alternatif, daha düşük olası tahminler alın
- Segmentasyon sonucuna, yani tanınan karakterler, bunları oluşturan noktalar ve fırçalar gibi.
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ç nesnesiyle çözümlenen vaat döndürür. Tarayıcı, geliştiricinin belirttiği özelliği destekliyorsa 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 ayarlayıp yeni bir sorgu göndermek için kullanabilirsiniz.
Çizim başlat
Başvurunuzda, kullanıcının el yazısıyla giriş yaptığı bir giriş alanı sunmalısınız. Performansı artırmak için bu işlemi canvas nesnesi yardımıyla uygulamanız önerilir. Bu kısmın tam olarak uygulanması bu makalenin kapsam dışındadır ancak nasıl yapılacağını görmek için demoya bakabilirsiniz.
Yeni bir çizim başlatmak için tanıyıcıda startDrawing()
yöntemini çağırın. Bu yöntemde, tanıma algoritmasında ince ayar yapmak için farklı ipuçları içeren bir nesne kullanılır. Tüm ipuçları isteğe bağlıdır:
- Girilen metnin 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ıyı tanımlayabilecek karakterlerin ("grafikler") bir listesi
(
graphemeSet
)
El Yazısı Tanıma API'si, herhangi bir işaretleme cihazından gelen girişleri tüketmek için soyut bir arayüz sağlayan İşaretçi Etkinlikleri ile birlikte iyi performans gösterir. İş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 çizimi, el yazısı alanında bir pointerdown
etkinliğinin ilk oluşumunda otomatik olarak oluşturulmuştur. pointerType
boş veya özel bir değere ayarlanmış olabileceğinden, çizimin giriş türü için yalnızca desteklenen değerlerin ayarlandığından emin olmak için tutarlılık kontrolü yaptı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);
});
Çizgi ekle
pointerdown
etkinliği yeni bir çizgiye başlamak için de doğru yerdir. Bunu yapmak için yeni bir HandwritingStroke
örneği oluşturun. Ayrıca, geçerli zamanı, ona daha sonra eklenecek noktalar için referans noktası olarak saklamanız gerekir:
function startStroke(event) {
activeStroke = {
stroke: new HandwritingStroke(),
startTime: Date.now(),
};
addPoint(event);
}
Nokta ekleyin
Fırçayı oluşturduktan sonra, ilk noktayı doğrudan ona eklemeniz gerekir. Daha sonra başka noktalar ekleyeceklerinizden, nokta oluşturma mantığını ayrı bir yöntemle uygulamak mantıklıdır. Aşağıdaki örnekte addPoint()
yöntemi, geçen süreyi referans zaman damgasına göre hesaplar.
Geçici bilgi isteğe bağlıdır, ancak tanıma kalitesini iyileştirebilir. Ardından, işaretçi etkinliğinden X ve Y koordinatlarını okur ve noktayı mevcut fırçaya ekler.
function addPoint(event) {
const timeElapsed = Date.now() - activeStroke.startTime;
activeStroke.stroke.addPoint({
x: event.offsetX,
y: event.offsetY,
t: timeElapsed,
});
}
pointermove
etkinlik işleyici, işaretçi ekran boyunca hareket ettirildiğinde çağrılır. Bu noktaların fırçaya da eklenmesi gerekir. İşaretçi "aşağı" durumda değilse de (örneğin, fare düğmesine basmadan imleci ekran üzerinde hareket ettirirken) etkinlik yükseltilebilir. Aşağıdaki örnekte bulunan etkinlik işleyici, etkin bir çizgi olup olmadığını kontrol eder ve yeni noktayı 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 çiziminize çizgi ekleyebilirsiniz. Aşağıdaki örnek de activeStroke
öğesini sıfırlar. Böylece pointermove
işleyici, tamamlanan fırçaya nokta eklemez.
Şimdi sıra, çizim üzerinde getPrediction()
yöntemini çağırarak kullanıcının girişini tanımaya geliyor. Tanıma işlemi genellikle birkaç yüz milisaniyeden kısa sürer. Böylece, gerekirse tahminleri tekrar tekrar çalıştırabilirsiniz. Aşağıdaki örnekte, tamamlanan her çizgiden sonra yeni bir tahmin çalıştırılmaktadı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ıralanan bir dizi tahminle çözümlenen bir söz döndürür. Öğe sayısı, alternatives
ipucuna aktardığınız değere bağlıdır. Bu diziyi, kullanıcıya olası eşleşme seçeneklerini sunmak ve bir seçenek belirlemesini sağlamak için kullanabilirsiniz. Alternatif olarak, en olası tahminden yararlanabilirsiniz. Örnekte ben bunu yapıyorum.
Tahmin nesnesi, tanınan metni ve isteğe bağlı bir segmentasyon sonucunu içerir. Bunu aşağıdaki bölümde açıklayacağız.
Segmentasyon sonuçlarıyla ayrıntılı analizler
Hedef platform tarafından desteklenirse tahmin nesnesi, bir segmentasyon sonucu da içerebilir.
Bu dizi, tanınan tüm el yazısı segmentini, tanınan kullanıcı tanımlı karakterin (grapheme
) tanınan metindeki (beginIndex
, endIndex
) konumuyla birlikte bu segmenti oluşturan çizgi ve noktalardan oluşan bir kombinasyonudur.
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 tuvaldeki tanınan grafemleri tekrar bulabilirsiniz.
Tam tanıma
Tanıma işlemi tamamlandıktan sonra HandwritingDrawing
üzerinde clear()
ve HandwritingRecognizer
üzerinde finish()
yöntemini çağırarak kaynakları serbest bırakabilirsiniz:
drawing.clear();
recognizer.finish();
Demo
Web bileşeni <handwriting-textarea>
, el yazısı tanıma özelliğine sahip kademeli olarak iyileştirilmiş bir düzenleme kontrolü uygular. Düzenleme denetiminin sağ alt köşesindeki düğmeyi tıklayarak çizim modunu etkinleştirirsiniz. Çizimi tamamladığınızda, web bileşeni otomatik olarak tanımayı başlatır ve tanınan metni düzenleme denetimine tekrar 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.
Web bileşeni, tanıma davranışını dışarıdan tanımlamak için languages
ve recognitiontype
dahil olmak üzere özellikler ve özellikler sunar. Kontrolün içeriğini value
özelliğiyle ayarlayabilirsiniz:
<handwriting-textarea languages="en" recognitiontype="text" value="Hello"></handwriting-textarea>
Değerde yapılan değişikliklerden haberdar olmak için input
etkinliğini dinleyebilirsiniz.
Glitch'teki bu demoyu kullanarak bileşeni deneyebilirsiniz. Ayrıca kaynak koda göz atmayı da unutmayın. Denetimi uygulamanızda kullanmak için npm'den edinin.
Güvenlik ve izinler
Chromium ekibi; kullanıcı denetimi, şeffaflık ve ergonomi dahil olmak üzere Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme bölümünde tanımlanan temel ilkeleri kullanarak El Yazısı Tanıma API'sini tasarladı ve uyguladı.
Kullanıcı denetimi
El Yazısı Tanıma API'si kullanıcı tarafından kapatılamaz. Sadece HTTPS üzerinden sunulan web siteleri için kullanılabilir ve sadece üst düzey göz atma bağlamından çağrılabilir.
Şeffaflık
El yazısı tanımanın etkin olup olmadığına dair herhangi bir gösterge görünmez. Tarayıcı, dijital parmak izi almayı önlemek için karşı önlemler alır. Örneğin, olası kötüye kullanım tespit edildiğinde kullanıcıya bir izin mesajı gösterilir.
İzin kalıcılığı
El Yazısı Tanıma API'si şu anda herhangi bir izin istemi göstermemektedir. Bu nedenle, iznin hiçbir şekilde kullanılması gerekmez.
Geri bildirim
Chromium ekibi, Handwriting Recognition API ile ilgili deneyimlerinizi öğrenmek istiyor.
Bize API tasarımından bahsedin
API'nin beklediğiniz gibi çalışmayan bir yönü var mı? Ya da fikrinizi uygulamak için gereken eksik yöntemler veya özellikler var mı? Güvenlik modeliyle ilgili sorunuz veya yorumunuz mu var? İlgili GitHub kod deposunda spesifikasyon sorunu oluşturun veya mevcut bir soruna düşüncelerinizi ekleyin.
Uygulamayla ilgili bir sorunu bildirin
Chromium'un uygulamasında bir hata buldunuz mu? Yoksa uygulama, spesifikasyondan farklı mı?
new.crbug.com adresinden hata bildiriminde bulunun. Olabildiğince çok ayrıntı ve yeniden oluşturma ile ilgili basit talimatları eklediğinizden emin olun ve Bileşenler kutusuna Blink>Handwriting
yazın.
Glitch hızlı ve kolay yeniden oluşturma paylaşımı için idealdir.
API'ye desteği gösterin
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ı satıcılarına bu özellikleri desteklemenin ne kadar kritik olduğunu gösterir.
Bu aracı nasıl kullanmayı planladığınızı WICG Discourse ileti dizisinde paylaşın. #HandwritingRecognition
hashtag'ini kullanarak @ChromiumDev adresine bir tweet gönderin ve bunu nerede ve nasıl kullandığınızı bize bildirin.
Yararlı Bağlantılar
- Açıklayıcı
- Spesifikasyon taslağı
- GitHub deposu
- ChromeStatus
- Chromium hatası
- TAG incelemesi
- Prototip Oluşturma Amacı
- WebKit-Dev ileti dizisi
- Mozilla standart konumu
Teşekkür
Bu makale Joe Medley, Honglin Yu ve Jiewei Qian tarafından incelendi. Samir Bouaked tarafından Unsplash'teki lokomotif resim.