JavaScript, HTML, CSS e... !
15 commenti

Riconoscimento ottico dei caratteri (OCR)

Leggere il testo da un'immagine o da un file PDF tramite OCR con Google Apps Script

Con Google Apps Script è possibile estrarre il testo da un'immagine (JPG, PNG, GIF) o da un file PDF per salvarlo all'interno di un nuovo documento (Google Docs) in Google Drive.

Inutile spiegare gli enormi vantaggi di questa opportunità, basti pensare a quanti documenti scansionati abbiamo, o cartacei da scansionare per portare in formato digitale, e quanti di essi sono immagini statiche dove il testo non è selezionabile.
Con poche righe di codice in Apps Script abbiamo la possibilità di estrarre il testo in essi contenuto per poterlo utilizzare e rielaborare a proprio piacimento.

Lo script mostrato di seguito si avvale delle API di Google Drive (maggiori dettagli nella documentazione ufficiale, REST v2), in particolare quella per sfruttarne le potenzialità del relativo motore OCR (riconoscimento ottico dei caratteri), al fine di estrarre il testo contenuto all'interno di un'immagine in formato JPG che risiede sul web (la funzione accetta in ingresso un parametro definito dall'url del file che si intende processare) ed inserirlo in un Google Docs pronto per essere utilizzato:

function extractTextFromImageOrPDF(url) {
  
  // Accede alla risorsa web indicata e ne recupera i dati
  var blob = UrlFetchApp.fetch(url).getBlob();
  
  // Recupera i dettagli del file: il suo nome ed il tipo
  var resource = {
    title: blob.getName(),
    mimeType: blob.getContentType()
  };
  
  // Crea un file su Drive con le informazioni passate e parametri per abilitare l'ocr e relativa lingua
  // Per attivare questa funzionalità è necessario abilitare l'Advanced Drive API Service
  var file = Drive.Files.insert(resource, blob, {ocr: true, ocrLanguage: "it"});
  
  // Recupera l'istanza del doc appena creato
  var doc = DocumentApp.openById(file.id);
  
  // Recupera il testo, interpretato dall'OCR, dal doc
  var text = doc.getBody().getText();
  
  return text;
}

function main() {
  
  // Inserisci l'url dell'immagine o del pdf dal quale vuoi estrarre il testo
  var url = 'http://media.bigbossweb.com/corporates/.../dante_inferno_lettura_ocr_con_gas.jpg';

  // Richiama la funziona per il riconoscimento ottico dei caratteri (OCR)
  var text = extractTextFromImageOrPDF(url);
  
  // Il testo è visualizzabile nel log, oltre che su Drive nel file appena creato
  Logger.log(text);
}

L'utilizzo dello script di cui sopra è molto semplice, basterà sostituire l'url del file con quello di interesse (il file può risiedere anche su Drive), modificare il parametro ocrLanguage in base alla lingua del documento ed avviare la funzione main().
Nota che, utilizzando le API di Drive è necessario abilitare l'uso delle API dei Servizi Avanzati di Google nel progetto in questione (nel caso dello script oggetto del presente tutorial l'abilitazione deve essere effettuata per le Drive API).

Di seguito trovate un esempio del risultato per mostrare le potenzialità dello script appena proposto.

L'immagine utilizzata, presente in rete, è la seguente, Fig. 1:



immagine utilizzata come esempio per il recupero del testo tramite ocr

Fig. 1 - Immagine utilizzata come esempio per il recupero del testo tramite OCR con Apps Script


Eseguendo lo script dall'editor di Apps Script ed aprendo la finestra di log dal menu 'Visualizza -> Log' è subito possibile notare come il testo presente all'interno dell'immagine sia stato riconosciuto ed estratto, Fig. 2:



log di apps script dove viene mostrato il testo estratto dall'immagine tramite ocr

Fig. 2 - Log di Apps Script dove viene mostrato il testo estratto dall'immagine tramite l'API per OCR di Drive


Lo stesso contenuto è stato inserito in un Google Docs, presente su Drive con lo stesso nome del file originale, pronto per essere utilizzato, Fig. 3:



ldocumento google dove viene mostrato il testo estratto dall'immagine tramite ocr

Fig. 3 - Documento Google dove viene mostrato il testo estratto dall'immagine con Apps Script tramite l'API per OCR di Drive


Ci sono alcuni suggerimenti da tenere in considerazione al fine di ottenere un risultato ottimale, come ad esempio la dimensione del font che non deve essere inferiore ai 10px, la dimensione del file che non deve superare i 2MB oppure l'orientamento del documento da prevedere prima della sua elaborazione. Per la lista completa dei suggerimenti rimando alla pagina ufficiale di supporto della guida di Google Drive relativa alla conversione di pdf e file fotografici in testo.

Tags

Michele Pisani

Michele Pisani

Sviluppatore Javascript ed esperto in Digital Analytics

L'esperienza nel settore Digital Analytics unita ad anni di sviluppo in Javascript ha trovato la massima espressione in Google Apps Script che mi ha permesso, con estrema facilità e poche righe di codice, di realizzare potenti applicazioni interattive e processi automatizzati integrati con i prodotti della G Suite.

Come contattarmi
scrivi un commento

15 Commenti

  1. Sunday, February 25, 2018 alle ore 20:19 mauro

    trovo molto interresanti tutti i tuoi tutorial posso chiederti alla fine di automattizare i processi se io avessi piu' file in una cartella di drive posso dare in pasto queta cartella al programma tipo con l'istruzione
    es. var url = DriveApp.getFoldersByName(name).searchFiles(); e poi far seguire un ciclo (for x) in modo da fargli passare ogni file ed eventualmente se ne viene aggiunto uno di nuovo? tu cosa ne pensi ?? GRAZIE

    Rispondi a questo commento
    • Monday, February 26, 2018 alle ore 00:45 Michele PisaniAutore

      Ciao Mauro,
      il metodo searchFiles così come quello searchFolders, si aspettano come parametro un criterio di ricerca (come da documentazione ufficiale: https://developers.google.com/apps-script/reference/drive/drive-app#searchfilesparams).
      Nel modo in cui lo hai impostato credo che ti possa essere restituito l'errore 'Impossibile trovare il metodo searchFiles()'.
      Di seguito un esempio funzionante per la ricerca in Drive di tutte le cartelle che contengono nel nome la stringa definita:


      function searchFoldersContainsWord() {
      var folder_part_name = 'test';
      var folders = DriveApp.searchFolders("title contains '" + folder_part_name + "'");
      while (folders.hasNext()) {
      var folder = folders.next();
      Logger.log(folder.getName() + ': ' + folder.getId());
      }
      }


      Personalmente utilizzerei i classici metodi getFiles() e getFolder() per il recupero di tutti i file all'interno di una cartella.
      Un esempio può essere il seguente:


      function getFilesInAFolder() {
      var folder_name = 'nome_cartella';
      var folders = DriveApp.getFoldersByName(folder_name)
      while (folders.hasNext()) {
      var folder = folders.next();
      var files = folder.getFiles();
      while (files.hasNext()){
      file = files.next();
      Logger.log(file);
      }
      }
      }


      Nel caso tu abbia bisogno di riconoscere i file nuovi da quelli già processati devi inventarti qualcosa come ad esempio rinominare quelli già gestiti (e quindi escluderli all'interno del ciclo successivo) oppure spostarli in un'altra cartella, come descritto nell'articolo:

      Spostare i file tra le cartelle di Google Drive con Google Apps Script
      https://www.appsscript.it/tutorial/spostare-i-file-tra-le-cartelle-di-google-drive-con-google-apps-script/

      Rispondi a questo commento
      • Monday, February 26, 2018 alle ore 22:30 mauro

        grazie infinete ora mi metto a studiare , sei sempre molto gentile

  2. Thursday, March 22, 2018 alle ore 07:27 marco

    Salve sta studiando questo script (che debbo dire molto interessante) pero' mi da un errore nell'esecuzione alla riga 14
    var file = Drive.Files.insert(resource, blob, {ocr: true, ocrLanguage: "it"});
    mi dice "drive non definito" dove sto sbagliando (ho attivato le funzionalita' delle api)
    https://drive.google.com/open?id=18AQVEyBt3kQHoRsJiCa16E1lFFyUNKY8
    grazie :)

    Rispondi a questo commento
    • Friday, March 23, 2018 alle ore 00:29 Michele PisaniAutore

      Ciao Marco,
      oltre ad abilitare le API dalla Console API Google devi attivare le Drive API nei Servizi avanzati di Google dall'editor di script alla voce di menu 'Risorse > Servizi avanzati di Google ...'..

      Rispondi a questo commento
      • Friday, March 23, 2018 alle ore 07:43 MARCO

        Grazie per il suggerimento dopo aver attivato le drive api mi da queesto errore sempre sulla riga relativa all' ocr Spiacenti. Si è verificato un errore del server. Attendi e riprova. (riga 14, file "Codice") ho provato a dare il link di varie immagini con testo trovate in web sia jpg che png
        grazie per tutto

  3. Thursday, March 29, 2018 alle ore 12:40 mauro

    anch'io sto studiando queste righe di codice che trovo davvero scritte bene , ho notato che lo script funziona se togliamo il riferimento alla lingua {ocr: true, } , se volessi dare alla funzione una serie file invece di un url come debbo fare (i file sono in drive) , sto cercando di rinominare i file con i primi 10 caratteri che vengono letti dall'ocr , se riesco a farlo pubblico lo script

    Rispondi a questo commento
    • Thursday, March 29, 2018 alle ore 22:53 Michele PisaniAutore

      Ciao Mauro,
      hai provato a recuperare l'url del file con la funzione getUrl()?
      In base alla porzione di codice che ti ho indicato nei primi commenti (che effettua un ciclo sui file all'interno di una cartella), puoi recuperare l'URL del file processato con:

      file.getUrl()

      Rispondi a questo commento
      • Friday, March 30, 2018 alle ore 19:45 mauro

        grazie , avevo gia provato mettendogli manualmente ip di un file del drive , ma facendo cosi mi genera un errore tipo "OCR is not supported for files of type text/html (riga 42, file "Codice")" al contrario se gli do un indirizzo internet https://sito.it/foto.jpg lo script funziona regolarmente.. ps buona pasqua a tutti...

        • Friday, July 20, 2018 alle ore 23:16 Michele PisaniAutore

          Ciao Mauro,
          effettuando delle prove su un progetto sul quale sto lavorando ho trovato la soluzione per la conversione di file pdf (anche se il testo all'interno è una scansione) presenti direttamente in Google Drive.
          Il codice è esattamente lo stesso proposto nell'articolo, con la differenza che per recuperare il Blob del file la riga di codice da utilizzare è la seguente:

          var blob = DriveApp.getFileById('FILE_ID').getBlob();


          Dove FILE_ID è l'id del file presente su Drive (che puoi recuperare in modo programmatico oppure manualmente cliccando con il tasto destro sul file e poi su 'Ottieni link condivisibile').

  4. Saturday, July 21, 2018 alle ore 09:14 William

    Buongiorno, è possibile con app script creare una maschera che intercetta dei pdf all'interno di una cartella di drive in base a nome , cognome all'interno del pdf? Grazie mille William

    Rispondi a questo commento
    • Saturday, July 21, 2018 alle ore 10:21 Michele PisaniAutore

      Ciao William,
      quello che mi viene in mente, concettualmente parlando poi lato sviluppo serviranno le dovute accortezze e controlli del caso, è processare i pdf all'interno della cartella su Drive leggendoli uno ad uno tramite OCR (ovvero con la porzione di codice proposta in questo tutorial, con una piccola differenza che ti scrivo qui sotto) in modo da avere il contenuto del testo in una variabile dove poterlo leggere.

      Considerando che i tuoi pdf si trovano su Google Drive, per riferirsi ad un file direttamente su Drive anziché su un url esterno, la differenza rispetto al codice del tutorial è alla riga per recuperare il Blob del file, pertanto al posto di questa istruzione:

      var blob = UrlFetchApp.fetch(url).getBlob();


      Utilizzare la seguente:

      var blob = DriveApp.getFileById('FILE_ID').getBlob();


      Dove nel primo caso 'url' si riferisce all'indirizzo fisico del file in rete mentre nel secondo caso, quello che serve a te, FILE_ID è l'id del file presente su Drive.

      Rispondi a questo commento
  5. Sunday, April 28, 2019 alle ore 21:20 Luca

    Michele, davvero molto interessante. Secondo te è possibile Acquisire il testo in una parte specifica del PDF. Per esempio in una determinata area della prima pagina?
    Questo perché in questo modo sarebbe possibile rinominare i file, E usare il risultato per indicizzare il file e creare un sistema di archiviazione documentale in base al risultato della scansione .

    Rispondi a questo commento
    • Monday, April 29, 2019 alle ore 00:10 Michele PisaniAutore

      Ciao Luca,
      puoi provare a controllare nella documentazione ufficiale relativa all'API Files:insert: https://developers.google.com/drive/api/v2/reference/files/insert se tra i parametri c'è qualcosa che pensi faccia al caso tuo. A me non sembra che sia previsto questo livello di dettaglio nell'identificare una porzione di una pagina; probabilmente con qualche elaborazione manuale si può riuscire ad ottenere qualcosa ma come riferimento non mi viene in mente altro che possa essere se non il contenuto testuale, quindi poco funzionale e non scalabile.

      Rispondi a questo commento

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato.I campi contrassegnati da un * sono obbligatori
Puoi utilizzare i seguenti tag nei commenti:
[bold]testo[/bold] se vuoi evidenziare un testo con il grassetto[code]function helloworld() { }[/code] se vuoi pubblicare una porzione di codice[url]https://www.appsscript.it[/url] se devi riferirti ad un indirizzo web