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 gestito e senza server per le API di Google Cloud che gestisce l'autenticazione e può essere richiamato dalla tua app per dispositivi mobili con SDK predefiniti.
Questa guida illustra 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 considera se questo meccanismo di autenticazione è sufficiente per il tuo caso d'uso prima di procedere.
Prima di iniziare
Configura il tuo progetto
Se non hai già aggiunto Firebase alla tua app, fallo seguendo i passaggi della guida introduttiva .Utilizza Swift Package Manager per installare e gestire le dipendenze di Firebase.
- In Xcode, con il progetto dell'app aperto, vai a File > Add Packages .
- Quando richiesto, aggiungi il repository SDK delle piattaforme Firebase Apple:
- Scegli la libreria Firebase ML.
- Al termine, Xcode inizierà automaticamente a risolvere e scaricare le tue dipendenze in background.
https://github.com/firebase/firebase-ios-sdk
Successivamente, esegui alcune configurazioni in-app:
- Nella tua app, importa Firebase:
Rapido
import FirebaseMLModelDownloader
Obiettivo-C
@import FirebaseMLModelDownloader;
Qualche altro passaggio di configurazione e siamo pronti per partire:
Se non hai già abilitato le API basate su cloud per il tuo progetto, fallo ora:
- Apri la pagina delle API Firebase ML della console Firebase.
Se non hai già aggiornato il tuo progetto al piano tariffario Blaze, fai clic su Aggiorna per farlo. (Ti verrà chiesto di eseguire l'upgrade solo se il tuo progetto non è nel piano Blaze.)
Solo i progetti di livello Blaze possono utilizzare le API basate su cloud.
- Se le API basate su cloud non sono già abilitate, fai clic su Abilita API basate su cloud .
- Configura le tue chiavi API Firebase esistenti per impedire l'accesso all'API Cloud Vision:
- Apri la pagina Credenziali della console Cloud.
- Per ogni chiave API nell'elenco, apri la visualizzazione di modifica e, nella sezione Restrizioni chiave, aggiungi all'elenco tutte le API disponibili tranne l'API Cloud Vision.
Distribuire la funzione richiamabile
Successivamente, distribuisci la funzione Cloud che utilizzerai per collegare la tua app e l'API Cloud Vision. Il repository functions-samples
contiene un esempio che puoi usare.
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 requisiti diversi.
Per implementare la funzione:
- Clonare o scaricare il repository functions-samples e passare alla directory
vision-annotate-image
:git clone https://github.com/firebase/functions-samples
cd vision-annotate-image
- Installa le dipendenze:
cd functions
npm install
cd ..
- Se non disponi dell'interfaccia a riga di comando di Firebase, installala .
- Inizializza un progetto Firebase nella directory
vision-annotate-image
. Quando richiesto, seleziona il tuo progetto nell'elenco.firebase init
- Distribuire la funzione:
firebase deploy --only functions:annotateImage
Aggiungi Firebase Auth alla tua app
La funzione richiamabile distribuita in precedenza rifiuterà qualsiasi richiesta da parte di utenti non autenticati della tua app. Se non lo hai già fatto, dovrai aggiungere Firebase Auth alla tua app.
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 ingresso
Per richiamare Cloud Vision, l'immagine deve essere formattata come stringa con codifica Base64. Per elaborareUIImage
:Rapido
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. Richiamare la funzione richiamabile per riconoscere il testo
Per riconoscere i punti di riferimento in un'immagine, richiama la funzione richiamabile passando una richiesta JSON Cloud Vision .Innanzitutto, inizializza un'istanza di Cloud Functions:
Rapido
lazy var functions = Functions.functions()
Obiettivo-C
@property(strong, nonatomic) FIRFunctions *functions;
Crea la richiesta. L'API Cloud Vision supporta due tipi di rilevamento del testo:
TEXT_DETECTION
eDOCUMENT_TEXT_DETECTION
. Consulta i documenti OCR di Cloud Vision per la differenza tra i due casi d'uso.Rapido
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"]} };
Infine, invoca la funzione:
Rapido
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. Estrarre il testo da blocchi di testo riconosciuto
Se l'operazione di riconoscimento del testo ha esito positivo, nel risultato dell'attività verrà restituita una risposta JSON di BatchAnnotateImagesResponse . Le annotazioni di testo si trovano nell'oggetto fullTextAnnotation
.
È possibile ottenere il testo riconosciuto come stringa nel campo text
. Per esempio:
Rapido
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
, puoi ottenere il testo riconosciuto nell'area e le coordinate di delimitazione dell'area. Per esempio:
Rapido
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];
}
}