browser.documentScan

Descrizione

Utilizza l'API chrome.documentScan per rilevare e recuperare immagini da scanner per documenti collegati.

L'API Document Scan è progettata per consentire ad app ed estensioni di visualizzare i contenuti dei documenti cartacei su uno scanner per documenti collegato.

Autorizzazioni

documentScan

Disponibilità

Chrome 44+ Solo ChromeOS
La disponibilità per i membri dell'API aggiunti in un secondo momento viene mostrata insieme a questi membri.

Concetti e utilizzo

Questa API supporta due metodi di scansione dei documenti. Se il tuo caso d'uso può funzionare con qualsiasi scanner e non richiede il controllo della configurazione, utilizza il metodo scan(). I casi d'uso più complessi richiedono una combinazione di metodi, supportati solo in Chrome 124 e versioni successive.

Scansione semplice

Per i casi d'uso semplici, ovvero quelli che possono funzionare con qualsiasi scanner e non richiedono il controllo della configurazione, chiama il numero scan(). Questo metodo accetta un oggetto ScanOptions e restituisce una promessa che viene risolta con un oggetto ScanResults. Le funzionalità di questa opzione sono limitate al numero di scansioni e ai tipi MIME che verranno accettati dal chiamante. Le scansioni vengono restituite come URL per la visualizzazione in un tag <img> per un'interfaccia utente.

Scansione complessa

Le scansioni complesse vengono eseguite in tre fasi, come descritto in questa sezione. Questo schema non descrive ogni argomento del metodo o ogni proprietà restituita in una risposta. Ha solo lo scopo di fornirti una guida generale alla scrittura del codice dello scanner.

Discovery

  1. Chiama il numero getScannerList(). Gli scanner disponibili vengono restituiti in una promessa che si risolve con un GetScannerListResponse.

    • L'oggetto di risposta contiene un array di oggetti ScannerInfo.
    • L'array può contenere più voci per un singolo scanner se questo supporta più protocolli o metodi di connessione.
  2. Seleziona uno scanner dall'array restituito e salva il valore della proprietà scannerId.

    Utilizza le proprietà dei singoli oggetti ScannerInfo per distinguere più oggetti per lo stesso scanner. Gli oggetti dello stesso scanner avranno lo stesso valore per la proprietà deviceUuid. ScannerInfo contiene anche una proprietà imageFormats contenente un array di tipi di immagini supportati.

Configurazione dello scanner

  1. Chiama openScanner(), passando l'ID scanner salvato. Restituisce una promessa che si risolve con un OpenScannerResponse. L'oggetto di risposta contiene:

    • Una proprietà scannerHandle, che dovrai salvare.

    • Una proprietà delle opzioni contenente proprietà specifiche dello scanner, che dovrai impostare. Per saperne di più, consulta Recuperare le opzioni dello scanner.

  2. (Facoltativo) Se hai bisogno che l'utente fornisca valori per le opzioni dello scanner, crea un'interfaccia utente. Avrai bisogno delle opzioni dello scanner fornite nel passaggio precedente e dovrai recuperare i gruppi di opzioni forniti dallo scanner. Per ulteriori informazioni, consulta la sezione Costruire un'interfaccia utente.

  3. Crea un array di oggetti OptionSetting utilizzando valori forniti dall'utente o programmatici. Per saperne di più, consulta Impostare le opzioni dello scanner.

  4. Passa l'array di oggetti OptionSetting a setOptions() per impostare le opzioni per lo scanner. Restituisce una promessa che si risolve con un SetOptionsResponse. Questo oggetto contiene una versione aggiornata delle opzioni dello scanner recuperate nel passaggio 1 della configurazione dello scanner.

    Poiché la modifica di un'opzione può alterare i vincoli di un'altra, potresti dover ripetere questi passaggi più volte.

Analisi in corso

  1. Crea un oggetto StartScanOptions e passalo a startScan(). Restituisce una promessa che si risolve con un StartScanResponse. La proprietà job è un handle che utilizzerai per leggere i dati di scansione o annullare la scansione.

  2. Passa l'handle del job a readScanData(). Restituisce una promessa che viene risolta con un oggetto ReadScanDataResponse. Se i dati sono stati letti correttamente, la proprietà result è uguale a SUCCESS e la proprietà data contiene un ArrayBuffer con parte della scansione. Tieni presente che estimatedCompletion contiene una percentuale stimata del totale dei dati pubblicati finora.

  3. Ripeti il passaggio precedente finché la proprietà result non è uguale a EOF o non si verifica un errore.

Al termine della scansione, chiama closeScanner() con l'handle dello scanner salvato nel passaggio 3. Restituisce una promessa che si risolve con un CloseScannerResponse. Chiamare cancelScan() in qualsiasi momento dopo la creazione del job interromperà la scansione.

Oggetti di risposta

Tutti i metodi restituiscono una promessa che viene risolta con un oggetto di risposta di qualche tipo. La maggior parte di questi contiene una proprietà result il cui valore è un membro di OperationResult. Alcune proprietà degli oggetti di risposta non contengono valori, a meno che il valore di result non sia specifico. Queste relazioni sono descritte nel riferimento per ogni oggetto risposta.

Ad esempio, OpenScannerResponse.scannerHandle avrà un valore solo quando OpenScannerResponse.result è uguale a SUCCESS.

Opzioni dello scanner

Le opzioni dello scanner variano notevolmente in base al dispositivo. Di conseguenza, non è possibile riflettere le opzioni dello scanner direttamente nell'API documentScan. Per ovviare a questo problema, OpenScannerResponse (recuperato utilizzando openScanner()) e SetOptionsResponse (l'oggetto di risposta per setOptions()) contengono una proprietà options, ovvero un oggetto contenente opzioni specifiche dello scanner. Ogni opzione è un mapping chiave-valore in cui la chiave è un'opzione specifica del dispositivo e il valore è un'istanza di ScannerOption.

La struttura in genere è la seguente:

{
  "key1": { scannerOptionInstance }
  "key2": { scannerOptionInstance }
}

Ad esempio, immagina uno scanner che restituisce opzioni denominate "source" e "resolution". La struttura dell'oggetto options restituito sarà simile al seguente esempio. Per semplicità, vengono mostrate solo le risposte parziali ScannerOption.

{
  "source": {
    "name": "source",
    "type": OptionType.STRING,
...
},
  "resolution": {
    "name": "resolution",
    "type": OptionType.INT,
...
  },
...
}

Costruire un'interfaccia utente

Sebbene non sia obbligatorio per utilizzare questa API, potresti voler consentire a un utente di scegliere il valore per una determinata opzione. Ciò richiede un'interfaccia utente. Utilizza OpenScannerResponse (aperto da openScanner()) per recuperare le opzioni dello scanner collegato, come descritto nella sezione precedente.

Alcuni scanner raggruppano le opzioni in modi specifici per il dispositivo. Non influiscono sul comportamento delle opzioni, ma poiché questi gruppi potrebbero essere menzionati nella documentazione del prodotto di uno scanner, devono essere mostrati all'utente. Puoi recuperare questi gruppi chiamando il numero getOptionGroups(). Restituisce una promessa che viene risolta con un oggetto GetOptionGroupsResponse. La proprietà groups contiene un array di gruppi specifico per lo scanner. Utilizza le informazioni di questi gruppi per organizzare le opzioni nel OpenScannerResponse per la visualizzazione.

{
  scannerHandle: "123456",
  result: SUCCESS,
  groups: [
    {
      title: "Standard",
      members: [ "resolution", "mode", "source" ]
    }
  ]
}

Come indicato in Configurazione dello scanner, la modifica di un'opzione può alterare i vincoli di un'altra opzione. Per questo motivo, setOptionsResponse (l'oggetto di risposta per setOptions()) contiene un'altra proprietà options. Utilizza questo comando per aggiornare l'interfaccia utente. Poi ripeti l'operazione in base alle necessità finché non hai impostato tutte le opzioni.

Impostare le opzioni dello scanner

Imposta le opzioni dello scanner passando un array di oggetti OptionSetting a setOptions(). Per un esempio, consulta la sezione Scansionare una pagina in formato lettera.

Esempi

Recuperare una pagina come blob

Questo esempio mostra un modo per recuperare una pagina dallo scanner come blob e dimostra l'utilizzo di startScan() e readScanData() utilizzando il valore di OperationResult.

async function pageAsBlob(handle) {
  let response = await browser.documentScan.startScan(
      handle, {format: "image/jpeg"});
  if (response.result != browser.documentScan.OperationResult.SUCCESS) {
    return null;
  }
  const job = response.job;

  let imgParts = [];
  response = await browser.documentScan.readScanData(job);
  while (response.result == browser.documentScan.OperationResult.SUCCESS) {
    if (response.data && response.data.byteLength > 0) {
        imgParts.push(response.data);
    } else {
      // Delay so hardware can make progress.
      await new Promise(r => setTimeout(r, 100));
    }
    response = await browser.documentScan.readScanData(job);
  }
  if (response.result != browser.documentScan.OperationResult.EOF) {
    return null;
  }
  if (response.data && response.data.byteLength > 0) {
    imgParts.push(response.data);
  }
  return new Blob(imgParts, { type: "image/jpeg" });
}

Scansionare una pagina in formato Letter

Questo esempio mostra come selezionare uno scanner, impostarne le opzioni e aprirlo. Recupera quindi i contenuti di una singola pagina e chiude lo scanner. Questa procedura mostra l'utilizzo di getScannerList(), openScanner(), setOptions() e closeScanner(). Tieni presente che i contenuti della pagina vengono recuperati chiamando la funzione pageAsBlob() dell'esempio precedente.

async function scan() {
    let response = await browser.documentScan.getScannerList({ secure: true });
    let scanner = await browser.documentScan.openScanner(
        response.scanners[0].scannerId);
    const handle = scanner.scannerHandle;

    let options = [];
    for (source of scanner.options["source"].constraint.list) {
        if (source.includes("ADF")) {
            options.push({
                name: "source",
                type: browser.documentScan.OptionType.STRING,
                value: { value: source }
            });
            break;
        }
    }
    options.push({
        name: "tl-x",
        type: browser.documentScan.OptionType.FIXED,
        value: 0.0
    });
    options.push({
        name: "br-x",
        type: browser.documentScan.OptionType.FIXED,
        value: 215.9  // 8.5" in mm
    });
    options.push({
        name: "tl-y",
        type: browser.documentScan.OptionType.FIXED,
        value: 0.0
    });
    options.push({
        name: "br-y",
        type: browser.documentScan.OptionType.FIXED,
        value: 279.4  // 11" in mm
    });
    response = await browser.documentScan.setOptions(handle, options);

    let imgBlob = await pageAsBlob(handle);
    if (imgBlob != null) {
        // Insert imgBlob into DOM, save to disk, etc
    }
    await browser.documentScan.closeScanner(handle);
}

Mostra la configurazione

Come indicato altrove, per mostrare a un utente le opzioni di configurazione di uno scanner è necessario chiamare getOptionGroups() oltre alle opzioni dello scanner restituite da una chiamata a openScanner(). In questo modo, le opzioni possono essere mostrate agli utenti nei gruppi definiti dal produttore. Questo esempio mostra come farlo.

async function showConfig() {
  let response = await browser.documentScan.getScannerList({ secure: true });
  let scanner = await browser.documentScan.openScanner(
      response.scanners[0].scannerId);
  let groups = await browser.documentScan.getOptionGroups(scanner.scannerHandle);

  for (const group of groups.groups) {
    console.log("=== " + group.title + " ===");
    for (const member of group.members) {
      const option = scanner.options[member];
      if (option.isActive) {
        console.log("  " + option.name + " = "