Catch up on everthing we announced at this year's Firebase Summit. Learn more

Riconosci il testo nelle immagini in modo sicuro con Cloud Vision utilizzando l'autenticazione e le funzioni Firebase su piattaforme Apple

Per chiamare un'API Google Cloud dalla tua app, devi creare un'API REST intermedia che gestisca l'autorizzazione e protegga i valori segreti come le chiavi API. Devi quindi scrivere il codice nella tua app mobile per autenticarti e comunicare con questo servizio intermedio.

Un modo per creare questa API REST consiste nell'utilizzare Firebase Authentication and Functions, che ti offre un gateway serverless gestito per le API di Google Cloud che gestisce l'autenticazione e può essere chiamato dalla tua app mobile con SDK predefiniti.

Questa guida mostra come utilizzare questa tecnica per chiamare l'API Cloud Vision dalla tua app. Questo metodo consentirà a tutti gli utenti autenticati di accedere ai servizi fatturati di Cloud Vision tramite il tuo progetto Cloud, quindi valuta se questo meccanismo di autenticazione è sufficiente per il tuo caso d'uso prima di procedere.

Prima di iniziare

Configura il tuo progetto

Se non si è già aggiunto Firebase per la vostra applicazione, farlo seguendo la procedura descritta nella guida introduttiva .

Usa Swift Package Manager per installare e gestire le dipendenze Firebase.

  1. In Xcode, con il progetto applicazione aperta, passare a File> Pacchetti Swift> Aggiungi dipendenza pacchetto.
  2. Quando richiesto, aggiungi il repository SDK delle piattaforme Apple Firebase:
  3.   https://github.com/firebase/firebase-ios-sdk
      
  4. Scegli la libreria Firebase ML.
  5. Al termine, Xcode inizierà automaticamente a risolvere e scaricare le tue dipendenze in background.

Quindi, esegui alcune impostazioni in-app:

  1. Nella tua app, importa Firebase:

    Swift

    import Firebase

    Obiettivo-C

    @import Firebase;

Ancora qualche passaggio di configurazione e siamo pronti per partire:

  1. Se non hai già abilitato le API basate su cloud per il tuo progetto, fallo ora:

    1. Aprire la pagina di Firebase ML API della console Firebase.
    2. Se non avete già aggiornato il vostro progetto per il piano tariffario Blaze, fare clic su Aggiorna per farlo. (Ti verrà richiesto di eseguire l'aggiornamento solo se il tuo progetto non è nel piano Blaze.)

      Solo i progetti di livello Blaze possono utilizzare le API basate su cloud.

    3. Se le API basate su cloud non sono già abilitati, fare clic su Attiva API basate su cloud.
  2. Configura le tue chiavi API Firebase esistenti per impedire l'accesso all'API Cloud Vision:
    1. Aprire la Credenziali pagina della console Cloud.
    2. Per ogni chiave API nella lista, aprire la vista editing, e nella sezione Restrizioni chiave, aggiungere tutte le API disponibili ad eccezione del Cloud API Vision alla lista.

Distribuire la funzione richiamabile

Successivamente, distribuisci la funzione cloud che utilizzerai per collegare la tua app e l'API Cloud Vision. L' functions-samples repository contiene un esempio è possibile utilizzare.

Per impostazione predefinita, l'accesso all'API Cloud Vision tramite questa funzione consentirà solo agli utenti autenticati della tua app di accedere all'API Cloud Vision. È possibile modificare la funzione per esigenze diverse.

Per distribuire la funzione:

  1. Clone o scaricare le funzioni-campioni pronti contro termine e passare alla vision-annotate-image di repertorio:
    git clone https://github.com/firebase/functions-samples
    cd vision-annotate-image
    
  2. Installare le dipendenze:
    cd functions
    npm install
    cd ..
    
  3. Se non si dispone del Firebase CLI, installarlo .
  4. Inizializzare un progetto di Firebase nella vision-annotate-image directory. Quando richiesto, seleziona il tuo progetto nell'elenco.
    firebase init
  5. Distribuire la funzione:
    firebase deploy --only functions:annotateImage

Aggiungi Firebase Auth alla tua app

La funzione richiamabile distribuita sopra rifiuterà qualsiasi richiesta proveniente da utenti non autenticati della tua app. Se non lo avete già fatto, è necessario aggiungere Firebase Auth per la vostra applicazione.

Aggiungi le dipendenze necessarie alla tua app

Utilizza Swift Package Manager per installare la libreria Cloud Functions for Firebase.

Ora sei pronto per iniziare a riconoscere il testo nelle immagini.

1. Preparare l'immagine di input

Per chiamare Cloud Vision, l'immagine deve essere formattata come stringa con codifica base64. Per elaborare un UIImage :

Swift

guard let imageData = uiImage.jpegData(compressionQuality: 1.0f) else { return }
let base64encodedImage = imageData.base64EncodedString()

Obiettivo-C

NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f);
NSString *base64encodedImage =
  [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];

2. Invocare la funzione richiamabile per riconoscere il testo

Per riconoscere punti di riferimento in un'immagine, richiamare la funzione callable passando una richiesta JSON Vision Cloud .

  1. Innanzitutto, inizializza un'istanza di Cloud Functions:

    Swift

    lazy var functions = Functions.functions()
    

    Obiettivo-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. Crea la richiesta. Il Cloud API Vision supporta due tipi di rilevazione del testo: TEXT_DETECTION e DOCUMENT_TEXT_DETECTION . Vedi le Vision OCR Docs cloud per la differenza tra i due casi d'uso.

    Swift

    let requestData = [
      "image": ["content": base64encodedImage],
      "features": ["type": "TEXT_DETECTION"],
      "imageContext": ["languageHints": ["en"]]
    ]
    

    Obiettivo-C

    NSDictionary *requestData = @{
      @"image": @{@"content": base64encodedImage},
      @"features": @{@"type": @"TEXT_DETECTION"},
      @"imageContext": @{@"languageHints": @[@"en"]}
    };
    
  3. Infine, invoca la funzione:

    Swift

    functions.httpsCallable("annotateImage").call(requestData) { (result, error) in
      if let error = error as NSError? {
        if error.domain == FunctionsErrorDomain {
          let code = FunctionsErrorCode(rawValue: error.code)
          let message = error.localizedDescription
          let details = error.userInfo[FunctionsErrorDetailsKey]
        }
        // ...
      }
      // Function completed succesfully
    }
    

    Obiettivo-C

    [[_functions HTTPSCallableWithName:@"annotateImage"]
                              callWithObject:requestData
                                  completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) {
            if (error) {
              if (error.domain == FIRFunctionsErrorDomain) {
                FIRFunctionsErrorCode code = error.code;
                NSString *message = error.localizedDescription;
                NSObject *details = error.userInfo[FIRFunctionsErrorDetailsKey];
              }
              // ...
            }
            // Function completed succesfully
            // Get information about labeled objects
    
          }];
    

3. Estrai il testo da blocchi di testo riconosciuto

Se l'operazione di riconoscimento del testo riesce, una risposta JSON di BatchAnnotateImagesResponse verrà restituito nel risultato dell'attività. Le annotazioni di testo possono essere trovati nel fullTextAnnotation oggetto.

È possibile ottenere il testo riconosciuto come una stringa nel text campo. Per esempio:

Swift

guard let annotation = (result?.data as? [String: Any])?["fullTextAnnotation"] as? [String: Any] else { return }
print("%nComplete annotation:")
let text = annotation["text"] as? String ?? ""
print("%n\(text)")

Obiettivo-C

NSDictionary *annotation = result.data[@"fullTextAnnotation"];
if (!annotation) { return; }
NSLog(@"\nComplete annotation:");
NSLog(@"\n%@", annotation[@"text"]);

È inoltre possibile ottenere informazioni specifiche per le regioni dell'immagine. Per ogni block , paragraph , word e symbol , è possibile ottenere il testo riconosciuto nella regione e le coordinate di delimitazione della regione. Per esempio:

Swift

guard let pages = annotation["pages"] as? [[String: Any]] else { return }
for page in pages {
var pageText = ""
guard let blocks = page["blocks"] as? [[String: Any]] else { continue }
for block in blocks {
    var blockText = ""
    guard let paragraphs = block["paragraphs"] as? [[String: Any]] else { continue }
    for paragraph in paragraphs {
    var paragraphText = ""
    guard let words = paragraph["words"] as? [[String: Any]] else { continue }
    for word in words {
        var wordText = ""
        guard let symbols = word["symbols"] as? [[String: Any]] else { continue }
        for symbol in symbols {
        let text = symbol["text"] as? String ?? ""
        let confidence = symbol["confidence"] as? Float ?? 0.0
        wordText += text
        print("Symbol text: \(text) (confidence: \(confidence)%n")
        }
        let confidence = word["confidence"] as? Float ?? 0.0
        print("Word text: \(wordText) (confidence: \(confidence)%n%n")
        let boundingBox = word["boundingBox"] as? [Float] ?? [0.0, 0.0, 0.0, 0.0]
        print("Word bounding box: \(boundingBox.description)%n")
        paragraphText += wordText
    }
    print("%nParagraph: %n\(paragraphText)%n")
    let boundingBox = paragraph["boundingBox"] as? [Float] ?? [0.0, 0.0, 0.0, 0.0]
    print("Paragraph bounding box: \(boundingBox)%n")
    let confidence = paragraph["confidence"] as? Float ?? 0.0
    print("Paragraph Confidence: \(confidence)%n")
    blockText += paragraphText
    }
    pageText += blockText
}

Obiettivo-C

for (NSDictionary *page in annotation[@"pages"]) {
  NSMutableString *pageText = [NSMutableString new];
  for (NSDictionary *block in page[@"blocks"]) {
    NSMutableString *blockText = [NSMutableString new];
    for (NSDictionary *paragraph in block[@"paragraphs"]) {
      NSMutableString *paragraphText = [NSMutableString new];
      for (NSDictionary *word in paragraph[@"words"]) {
        NSMutableString *wordText = [NSMutableString new];
        for (NSDictionary *symbol in word[@"symbols"]) {
          NSString *text = symbol[@"text"];
          [wordText appendString:text];
          NSLog(@"Symbol text: %@ (confidence: %@\n", text, symbol[@"confidence"]);
        }
        NSLog(@"Word text: %@ (confidence: %@\n\n", wordText, word[@"confidence"]);
        NSLog(@"Word bounding box: %@\n", word[@"boundingBox"]);
        [paragraphText appendString:wordText];
      }
      NSLog(@"\nParagraph: \n%@\n", paragraphText);
      NSLog(@"Paragraph bounding box: %@\n", paragraph[@"boundingBox"]);
      NSLog(@"Paragraph Confidence: %@\n", paragraph[@"confidence"]);
      [blockText appendString:paragraphText];
    }
    [pageText appendString:blockText];
  }
}