Ücretsiz APK oluştur

JavaScript köprü API'si

QR ve barkod tarayıcı

Tek bir promise ile Google'ın tarayıcı ekranı, AppMint.scanCode() - kamera izni yok; yaygın QR kodları için ayrıştırılmış URL, Wi-Fi, telefon veya kişi bilgisi.

AppMint.scanCode yardımcı#

AppMint.scanCode(options)

Örnek

Google'ın QR kodu ve barkod tarayıcı ekranını açar ve taranan şeyi size verir. Tek çağrı - kamera izni yok, <video> yok, kendi arayüzünüz yok.

Döndürür: her zaman tamamlanan bir Promise: {ok: true, value, displayValue, format, type, …} veya {ok: false, code, message}. Gerekli: açılacak bir şey yok. Telefonun Google Play hizmetlerine ihtiyacı var.

Herhangi bir kod:

async function scan() {
  if (!(window.AppMint && AppMint.scanCode)) { alert('Open this page in the app to scan'); return; }
  var r = await AppMint.scanCode();
  if (!r.ok) {
    if (r.code === 'cancelled') return;                          // the user closed the scanner
    if (r.code === 'unavailable') alert('The scanner is not available on this phone');
    else if (r.code === 'busy') alert('A scan is already open');
    else alert('Scan failed: ' + r.message);                     // 'failed'
    return;
  }
  console.log(r.value, r.format, r.type);   // "TICKET-4821", "qr_code", "text"
}

Yalnızca bazı biçimler ve hasarlı etiketler için "elle girin" seçeneği:

var r = await AppMint.scanCode({
  formats: ['ean_13', 'ean_8', 'upc_a', 'upc_e'],   // shop barcodes
  manualInput: true,                                // lets the user type the code
  autoZoom: true                                    // default true
});
if (r.ok) lookUpProduct(r.value);

Hazır parçalar - yalnızca r.type ile eşleşen parça bulunur:

var r = await AppMint.scanCode({ formats: ['qr_code'] });
if (r.ok) {
  if (r.type === 'url')     openLink(r.url.url);                      // url: { url, title }
  if (r.type === 'wifi')    showWifi(r.wifi.ssid, r.wifi.password, r.wifi.encryption); // 'wpa'|'wep'|'open'
  if (r.type === 'phone')   callNumber(r.phone);                      // a string
  if (r.type === 'email')   writeMail(r.email.address, r.email.subject, r.email.body);
  if (r.type === 'sms')     writeSms(r.sms.phoneNumber, r.sms.message);
  if (r.type === 'geo')     showMap(r.geo.lat, r.geo.lng);
  if (r.type === 'contact') addContact(r.contact.name, r.contact.organization, r.contact.phones, r.contact.emails);
}

Notlar: Biçim adları: qr_code, aztec, codabar, code_39, code_93, code_128, data_matrix, ean_8, ean_13, itf, pdf417, upc_a, upc_e (bilinmeyen adlar yok sayılır; hiçbiri = tüm biçimler). type şunlardan biridir: url, wifi, text, phone, email, sms, geo, contact, calendar, isbn, product, driver_license, unknown. Hata kodları: cancelled (kapatıldı, Geri ile de), unavailable (Play hizmetleri yok veya tarayıcı indirilemedi), busy (bir tarama zaten açık), failed. Bir telefonda ilk tarama, Play hizmetleri tarayıcıyı indirirken birkaç saniye sürebilir. Yapay zekayla oluşturulan uygulamalar @/lib/appmintNative içinden scanCode() kullanır; bu web'de de tarar.

AppMint.textRecognition yardımcı#

AppMint.textRecognition.recognize(image, {script}) / prepare(script, onProgress)

Örnek

Latin dışındaki betiklerde metin okur: Devanagari (Hintçe, Marathi, Nepalce …), Çince, Japonca ve Korece - ya da her betiği deneyip en çok karakterli okumayı tutan 'auto'. Aynı seçenek standart algılayıcıda da çalışır: new TextDetector({ script: 'devanagari' }). Seçenek olmadan her şey eskisi gibi Latin olarak okunur.

Döndürür: recognize() → {script, text, blocks: [{text, box, corners, lines}]} değerli bir Promise (script = kullanılan); bir DOMException ile reddedilir - bilinmeyen betik veya Google Play hizmetleri yoksa NotSupportedError, aksi halde OperationError. prepare() → {script, status: 'ready'} değerli bir Promise. Gerekli: Google Play hizmetleri. Her betiğin tanıyıcısı bir Play hizmetleri indirmesidir: kodunuzun adlandırdığı betikler uygulamayla birlikte kurulur, diğerleri ilk kullanımda.

Fotoğraftan Hintçe metin:

document.getElementById('photo').addEventListener('change', async function (e) {
  var file = e.target.files[0];
  if (!file || !(window.AppMint && AppMint.textRecognition)) return;
  try {
    var r = await AppMint.textRecognition.recognize(file, { script: 'devanagari' });
    document.getElementById('out').textContent = r.text;
  } catch (err) {
    alert('Could not read the photo: ' + err.name);
  }
});

Önce bir betiğin modelini ilerlemeyle birlikte indirin - aksi halde bir telefonda ilk kullanım indirmeyi bekler:

async function getReady() {
  var bar = document.getElementById('model-progress');
  await AppMint.textRecognition.prepare('japanese', function (s) {
    if (s.progress != null) bar.value = s.progress;      // 0..1 while 'downloading'
  });
  bar.hidden = true;
}

// The same states arrive as events, also when a recognize() call starts a download:
window.addEventListener('appmint:ocr-model', function (e) {
  console.log(e.detail.script, e.detail.status, e.detail.progress);   // 'downloading' | 'ready' | 'failed'
});

Karışık belgeler - uygulamanın beklediğiniz betikler arasından seçmesine izin verin:

var r = await AppMint.textRecognition.recognize(img, { script: 'auto', scripts: ['latin', 'chinese', 'korean'] });
console.log('read as ' + r.script + ': ' + r.text);

var lines = await new TextDetector({ script: 'korean' }).detect(img);   // standard shape, one entry per line

Notlar: scripts AppMint'in listesidir: latin, devanagari, chinese, japanese, korean. Arapça, Kiril, Tayca ve İbranice için cihaz üzerinde tanıyıcı yoktur. WebToApk.__ocrRecognizeWith(requestId, base64, optionsJson) dahili aktarımdır; yardımcıyı kullanın.

__ocrAvailable köprü#

window.WebToApk.__ocrAvailable(): Boolean

TextDetector / recognizeText(): Google Play hizmetleri mevcut (OCR modülünün yuvası).

Örnek

TextDetector arkasındaki dahili aktarım: Google Play hizmetlerinin (tanıyıcının geldiği yer) bu telefonda olup olmadığı. Sayfalar standart API'yi kullanır; bunu asla doğrudan çağırmayın - __ yöntemleri haber verilmeden değişebilir.

Döndürür: true veya false. false olduğunda TextDetector hiç yüklü değildir. Gerekli: hiçbir şey.

Genel API'yi kullanın:

if ('TextDetector' in window) scanButton.hidden = false;

Tarama akışı ile yazılan form arasında başlangıçta bir kez seçim yapın. Telefonda Google Play hizmetleri yoksa algılayıcı hiç bulunmaz; bu yüzden sayfa başka bir giriş yolu sunmalıdır:

function setUpReceiptEntry() {
  var canScan = typeof window.TextDetector === 'function';
  document.getElementById('scan-receipt').hidden = !canScan;
  document.getElementById('type-receipt').hidden = canScan;
  if (!canScan) document.getElementById('entry-hint').textContent =
    'Text scanning is not available on this phone. Type the total below.';
}
document.addEventListener('DOMContentLoaded', setUpReceiptEntry);

Var olan bir algılayıcı da çağrı anında tanımanın şu an kullanılamadığını bildirebilir. İki hatayı hata adıyla ayırt edin:

async function readLabel(img) {
  if (typeof window.TextDetector !== 'function') return null;
  try {
    var lines = await new TextDetector().detect(img);
    return lines.map(function (l) { return l.rawValue; }).join('\n');
  } catch (e) {
    if (e.name === 'NotSupportedError') showMessage('Text recognition is not available right now.');
    else showMessage('Could not read the label: ' + e.message);
    return null;
  }
}

Notlar: Uygulama kabuğunda uygulanmıştır (TextRecognitionBridge.kt).

__ocrRecognize köprü#

window.WebToApk.__ocrRecognize(requestId: String, base64: String)

[base64] (PNG/JPEG) içindeki metni tanır; yanıt `appmint:ocr {requestId, blocks|error}` olarak gelir.

Örnek

TextDetector.detect() arkasındaki dahili aktarım: bir PNG/JPEG içindeki metni tanır. Sayfalar standart API'yi kullanır; bunu asla doğrudan çağırmayın - __ yöntemleri haber verilmeden değişebilir.

Döndürür: hiçbir şey; yanıt appmint:ocr olayı {requestId, blocks:[{text, box, corners, lines}]} veya {requestId, error} (unavailable, bad-image, failed: …) olarak gelir. Gerekli: hiçbir şey.

Genel API'yi kullanın:

const lines = await new TextDetector().detect(document.getElementById('receipt'));
console.log(lines.map((l) => l.rawValue));

Kullanıcının seçtiği fotoğrafın metnini okuyun. detect() bir <img>, <canvas> veya Blob/File kabul eder ImageData:

<input type="file" id="doc" accept="image/*" capture="environment">
<pre id="out"></pre>
<script>
document.getElementById('doc').addEventListener('change', async function (e) {
  var file = e.target.files[0];
  if (!file || typeof window.TextDetector !== 'function') return;
  try {
    var lines = await new TextDetector().detect(file);
    document.getElementById('out').textContent = lines.map(function (l) { return l.rawValue; }).join('\n');
  } catch (err) {
    document.getElementById('out').textContent = 'Could not read the photo (' + err.name + ')';
  }
});
</script>

Tanınan her satırı görüntünün üzerinde çerçeveleyin. boundingBox görüntünün kendi piksellerindedir, bu yüzden gösterilen boyuta ölçekleyin. Görüntünün yüklenmesi bitmiş olmalıdır, yoksa detect() şu hatayla reddedilir: InvalidStateError:

async function highlightLines(img, overlay) {
  if (!img.complete) await new Promise(function (r) { img.onload = r; });
  var lines = await new TextDetector().detect(img);
  var sx = img.clientWidth / img.naturalWidth, sy = img.clientHeight / img.naturalHeight;
  overlay.innerHTML = '';
  lines.forEach(function (l) {
    var b = l.boundingBox, box = document.createElement('div');
    box.className = 'ocr-box';
    box.title = l.rawValue;
    box.style.cssText = 'position:absolute;left:' + b.x * sx + 'px;top:' + b.y * sy +
      'px;width:' + b.width * sx + 'px;height:' + b.height * sy + 'px';
    overlay.appendChild(box);
  });
}

Bir fişten tutar çıkarın. Canvas'ı kirleten çapraz kaynaklı bir görüntü SecurityError ile reddedilir, bu yüzden görseli uygulamanın kendi kaynağından sunun:

async function findTotal(img) {
  try {
    var lines = await new TextDetector().detect(img);
    var hit = lines.find(function (l) { return /total/i.test(l.rawValue); });
    var m = hit && hit.rawValue.match(/(\d+[.,]\d{2})/);
    return m ? parseFloat(m[1].replace(',', '.')) : null;
  } catch (e) {
    if (e.name === 'SecurityError') console.warn('Image is from another origin; load it from the app instead.');
    else console.warn('OCR failed:', e.name, e.message);
    return null;
  }
}

Notlar: Uygulama kabuğunda uygulanmıştır (TextRecognitionBridge.kt).

__ocrRecognizeWith köprü#

window.WebToApk.__ocrRecognizeWith(requestId: String, base64: String, optionsJson: String)

[__ocrRecognize], seçenekler [optionsJson] `{script: 'latin'|'devanagari'|'chinese'|'japanese'|'korean'|'auto', scripts?}` ile; `appmint:ocr` yanıtı ayrıca kullanılan `script` değerini de belirtir.

Örnek

AppMint.textRecognition ile birlikte belgelenmiştir - oradaki örnek bunu da gösterir.

Latin dışındaki betiklerde metin okur: Devanagari (Hintçe, Marathi, Nepalce …), Çince, Japonca ve Korece - ya da her betiği deneyip en çok karakterli okumayı tutan 'auto'. Aynı seçenek standart algılayıcıda da çalışır: new TextDetector({ script: 'devanagari' }). Seçenek olmadan her şey eskisi gibi Latin olarak okunur.

Döndürür: recognize() → {script, text, blocks: [{text, box, corners, lines}]} değerli bir Promise (script = kullanılan); bir DOMException ile reddedilir - bilinmeyen betik veya Google Play hizmetleri yoksa NotSupportedError, aksi halde OperationError. prepare() → {script, status: 'ready'} değerli bir Promise. Gerekli: Google Play hizmetleri. Her betiğin tanıyıcısı bir Play hizmetleri indirmesidir: kodunuzun adlandırdığı betikler uygulamayla birlikte kurulur, diğerleri ilk kullanımda.

Fotoğraftan Hintçe metin:

document.getElementById('photo').addEventListener('change', async function (e) {
  var file = e.target.files[0];
  if (!file || !(window.AppMint && AppMint.textRecognition)) return;
  try {
    var r = await AppMint.textRecognition.recognize(file, { script: 'devanagari' });
    document.getElementById('out').textContent = r.text;
  } catch (err) {
    alert('Could not read the photo: ' + err.name);
  }
});

Önce bir betiğin modelini ilerlemeyle birlikte indirin - aksi halde bir telefonda ilk kullanım indirmeyi bekler:

async function getReady() {
  var bar = document.getElementById('model-progress');
  await AppMint.textRecognition.prepare('japanese', function (s) {
    if (s.progress != null) bar.value = s.progress;      // 0..1 while 'downloading'
  });
  bar.hidden = true;
}

// The same states arrive as events, also when a recognize() call starts a download:
window.addEventListener('appmint:ocr-model', function (e) {
  console.log(e.detail.script, e.detail.status, e.detail.progress);   // 'downloading' | 'ready' | 'failed'
});

Karışık belgeler - uygulamanın beklediğiniz betikler arasından seçmesine izin verin:

var r = await AppMint.textRecognition.recognize(img, { script: 'auto', scripts: ['latin', 'chinese', 'korean'] });
console.log('read as ' + r.script + ': ' + r.text);

var lines = await new TextDetector({ script: 'korean' }).detect(img);   // standard shape, one entry per line

Notlar: scripts AppMint'in listesidir: latin, devanagari, chinese, japanese, korean. Arapça, Kiril, Tayca ve İbranice için cihaz üzerinde tanıyıcı yoktur. WebToApk.__ocrRecognizeWith(requestId, base64, optionsJson) dahili aktarımdır; yardımcıyı kullanın.

prepareTextRecognition köprü#

window.WebToApk.prepareTextRecognition(script: String): String

[script] için metin tanıyıcıyı kullanımdan önce indirir. "checking" döndürür (ardından `appmint:ocr-model {script, status: 'downloading'|'ready'|'failed', progress?}`), "unsupported-script" veya "unavailable" (Google Play hizmetleri yok).

Örnek

Bir betik için cihaz üzerindeki metin tanıyıcıyı kullanımdan önce indirir; böylece ilk recognize() beklemez. Sayfalar normalde bunu saran AppMint.textRecognition.prepare(script) işlevini çağırır.

Döndürür: hemen bir metin - "checking" (sonuç appmint:ocr-model olayları olarak gelir {script, status: 'downloading' | 'ready' | 'failed', progress?, error?}), "unsupported-script" veya "unavailable" (Google Play hizmetleri yok). 'auto' her betiği hazırlar. Gerekli: Google Play hizmetleri.

if (window.WebToApk && typeof window.WebToApk.prepareTextRecognition === 'function') {
  window.addEventListener('appmint:ocr-model', function (e) {
    if (e.detail.script !== 'chinese') return;
    if (e.detail.status === 'downloading') console.log('downloading', Math.round((e.detail.progress || 0) * 100) + '%');
    if (e.detail.status === 'ready') document.getElementById('scan').disabled = false;
    if (e.detail.status === 'failed') console.warn(e.detail.error);
  });
  var state = window.WebToApk.prepareTextRecognition('chinese');
  if (state !== 'checking') console.warn('Chinese text recognition: ' + state);
}

Hazırlayın, sonra sarmalayıcı üzerinden tarayın:

async function readSign(canvas) {
  if (!(window.AppMint && AppMint.textRecognition)) return null;
  try {
    await AppMint.textRecognition.prepare('japanese');
    return await AppMint.textRecognition.recognize(canvas, { script: 'japanese' });
  } catch (err) {
    console.warn('Text recognition:', err.name, err.message);   // e.g. NotSupportedError without Play services
    return null;
  }
}

Desteklenmeyen betikler ve eksik Play hizmetleri dönüş değerinde bildirilir:

const W = window.WebToApk;
if (W && typeof W.prepareTextRecognition === 'function') {
  const state = W.prepareTextRecognition('arabic');
  if (state === 'unsupported-script') showMessage('Arabic text cannot be read on the phone.');
  else if (state === 'unavailable') showMessage('Text recognition needs Google Play services.');
}

Notlar: Betikler: latin, devanagari, chinese, japanese, korean, auto. Telefonda zaten bulunan bir betik hemen ready yanıtı verir.

scanCode köprü#

window.WebToApk.scanCode(optionsJson: String, callbackId: String)

Google'ın kod tarayıcısını açar; [optionsJson] `{formats?, autoZoom?, manualInput?}`. AppMint.scanCode promise'ini [callbackId] ile tamamlar.

Örnek

AppMint.scanCode() işlevinin arkasındaki dahili altyapı - sayfalar bu Promise yardımcısını kullanır; o da Google'ın QR/barkod tarayıcısını açar ve sonuçla tamamlanır.

Döndürür: doğrudan hiçbir şey; sonuç AppMint.scanCode() promise'ini tamamlar. Gerekli: açılacak bir şey yok (kamera izni yok). Telefonun Google Play hizmetlerine ihtiyacı var.

Genel API:

async function scanTicket() {
  if (!(window.AppMint && AppMint.scanCode)) { alert('Open this page in the app to scan'); return; }
  var r = await AppMint.scanCode({ formats: ['qr_code'] });
  if (r.ok) checkTicket(r.value);                  // r.format, r.type, r.displayValue…
  else if (r.code !== 'cancelled') alert('Scan failed (' + r.code + ')');
}

Basılı bir QR kodundan Wi-Fi ağına katılın. Wi-Fi kodu type: 'wifi' ve bir wifi nesnesiyle döner:

async function scanWifi() {
  if (!(window.AppMint && AppMint.scanCode)) return;
  var r = await AppMint.scanCode({ formats: ['qr_code'] });
  if (!r.ok) { if (r.code !== 'cancelled') alert('Scan failed (' + r.code + ')'); return; }
  if (r.type !== 'wifi') { alert('That is not a Wi-Fi code.'); return; }
  showWifiCard(r.wifi.ssid, r.wifi.password, r.wifi.encryption);   // encryption: 'wpa' | 'wep' | 'open'
}

Bir ürünü mağaza barkoduyla arayın; etiket hasarlıysa kullanıcının rakamları yazmasına izin verin (manualInput). Bir telefonda ilk tarama tarayıcıyı indirebilir; çevrimdışıyken bu unavailable ile başarısız olur:

async function scanProduct() {
  if (!(window.AppMint && AppMint.scanCode)) { showManualEntry(); return; }
  var r = await AppMint.scanCode({ formats: ['ean_13', 'ean_8', 'upc_a', 'upc_e'], manualInput: true });
  if (r.ok) return lookUpProduct(r.value, r.format);            // e.g. '4006381333931', 'ean_13'
  if (r.code === 'busy') return;                                  // a scan is already open
  if (r.code === 'unavailable') alert('The scanner is not available: ' + r.message);
  else if (r.code !== 'cancelled') alert('Scan failed (' + r.code + ')');
}

Bir QR kodunun işaret ettiği her şeyi, çözülmüş değeriyle açın type:

async function scanAndOpen() {
  var r = await AppMint.scanCode({ formats: ['qr_code'], autoZoom: true });
  if (!r.ok) return;
  if (r.type === 'url') location.href = r.url.url;
  else if (r.type === 'phone') location.href = 'tel:' + r.phone;
  else if (r.type === 'email') location.href = 'mailto:' + r.email.address;
  else if (r.type === 'geo') showOnMap(r.geo.lat, r.geo.lng);
  else if (r.type === 'contact') saveContact(r.contact.name, r.contact.phones, r.contact.emails);
  else showText(r.displayValue);
}

Notlar: Ham yöntem optionsJson ({formats?, autoZoom?, manualInput?} JSON metni olarak) ve bir callbackId alır; yanıt yardımcının dahili yanıt tablosuna teslim edilir, bu yüzden doğrudan çağıran bir sayfa yanıt alamaz. Aynı anda yalnızca bir tarama çalışır - ikinci çağrı code: 'busy' yanıtı verir. Tüm sonuç alanları ve hata kodları için AppMint.scanCode sayfasına bakın.

Her belge derlemesinde uygulama çalışma zamanından ve örnek dosyalarından oluşturulur. Markdown olarak okuyun · Tüm aileler.

22.10.2026 tarihinde yayınlanan köprüyle karşılaştırılarak kontrol edildi.