Pour appeler une API Google Cloud depuis votre application, vous devez créer une API REST intermédiaire qui gère l'autorisation et protège les valeurs secrètes telles que les clés API. Vous devez ensuite écrire du code dans votre application mobile pour vous authentifier auprès de ce service intermédiaire et communiquer avec lui.
Pour créer cette API REST, vous pouvez utiliser Firebase Authentication et Functions, qui vous offrent une passerelle sans serveur gérée vers les API Google Cloud. Cette passerelle gère l'authentification et peut être appelée depuis votre application mobile avec des SDK prédéfinis.
Ce guide explique comment utiliser cette technique pour appeler l'API Cloud Vision depuis votre application. Cette méthode permettra à tous les utilisateurs authentifiés d'accéder aux services payants Cloud Vision via votre projet Cloud. Avant de continuer, vérifiez donc si ce mécanisme d'authentification est suffisant pour votre cas d'utilisation.
Avant de commencer
Configurez votre projet
Si vous n'avez pas encore ajouté Firebase à votre application, faites-le en suivant les étapes du guide de démarrage.Utilisez Swift Package Manager pour installer et gérer les dépendances Firebase.
- Dans Xcode, à partir de votre projet d'application ouvert, accédez à File > Add Packages (Fichier > Ajouter des packages).
- Lorsque vous y êtes invité, ajoutez le dépôt du SDK des plates-formes Firebase pour Apple :
- Choisissez la bibliothèque Firebase ML.
- Ajoutez l'indicateur
-ObjC
à la section Other Linker Flags (Autres indicateurs Linker) des paramètres de compilation de votre cible. - Lorsque vous avez terminé, Xcode commence à résoudre et à télécharger automatiquement vos dépendances en arrière-plan.
https://github.com/firebase/firebase-ios-sdk.git
Ensuite, effectuez la configuration dans l'application :
- Dans votre application, importez Firebase :
Swift
import FirebaseMLModelDownloader
Objective-C
@import FirebaseMLModelDownloader;
Il reste encore quelques étapes de configuration à suivre :
-
Si vous n'avez pas encore activé les API cloud pour votre projet, faites-le maintenant :
- Ouvrez la page API Firebase ML dans la console Firebase.
-
Si vous n'avez pas encore migré votre projet vers le forfait Blaze avec paiement à l'usage, cliquez sur Mettre à niveau pour le faire. (Vous serez invité à effectuer la mise à niveau uniquement si votre projet n'est pas associé au forfait Blaze.)
Seuls les projets associés au forfait Blaze peuvent utiliser les API basées sur le cloud.
- Si les API basées sur le cloud ne sont pas déjà activées, cliquez sur Activer les API basées sur le cloud.
- Configurez vos clés API Firebase existantes pour interdire l'accès à l'API Cloud Vision :
- Ouvrez la page Identifiants de la console Cloud.
- Pour chaque clé API de la liste, ouvrez la vue d'édition, puis dans la section "Restrictions de clé", ajoutez toutes les API disponibles sauf l'API Cloud Vision à la liste.
Déployer la fonction appelable
Ensuite, déployez la fonction Cloud que vous utiliserez pour faire le lien entre votre application et l'API Cloud Vision. Le dépôt functions-samples
contient un exemple que vous pouvez utiliser.
Par défaut, l'accès à l'API Cloud Vision via cette fonction n'autorise que les utilisateurs authentifiés de votre application à accéder à l'API Cloud Vision. Vous pouvez modifier la fonction pour répondre à différents besoins.
Pour déployer la fonction, procédez comme suit :
- Clonez ou téléchargez le dépôt functions-samples et accédez au répertoire
Node-1st-gen/vision-annotate-image
:git clone https://github.com/firebase/functions-samples
cd Node-1st-gen/vision-annotate-image
- Installez les dépendances :
cd functions
npm install
cd ..
- Si vous n'avez pas la CLI Firebase, installez-la.
- Initialisez un projet Firebase dans le répertoire
vision-annotate-image
. Lorsque vous y êtes invité, sélectionnez votre projet dans la liste.firebase init
- Déployez la fonction :
firebase deploy --only functions:annotateImage
Ajouter Firebase Auth à votre application
La fonction appelable déployée ci-dessus refusera toute requête provenant d'utilisateurs non authentifiés de votre application. Si vous ne l'avez pas encore fait, vous devrez ajouter Firebase Auth à votre application.
Ajouter les dépendances nécessaires à votre application
Utilisez Swift Package Manager pour installer la bibliothèque Cloud Functions pour Firebase.
Vous êtes maintenant prêt à commencer à reconnaître du texte dans des images.
1. Préparer l'image d'entrée
Pour appeler Cloud Vision, l'image doit être mise en forme sous forme de chaîne encodée en base64. Pour traiter unUIImage
:
Swift
guard let imageData = uiImage.jpegData(compressionQuality: 1.0) else { return } let base64encodedImage = imageData.base64EncodedString()
Objective-C
NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f); NSString *base64encodedImage = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
2. Appeler la fonction appelable pour reconnaître le texte
Pour reconnaître des points de repère dans une image, appelez la fonction appelable en transmettant une requête Cloud Vision JSON.Commencez par initialiser une instance de Cloud Functions :
Swift
lazy var functions = Functions.functions()
Objective-C
@property(strong, nonatomic) FIRFunctions *functions;
Créez la requête. L'API Cloud Vision est compatible avec deux types de détection de texte :
TEXT_DETECTION
etDOCUMENT_TEXT_DETECTION
. Consultez la documentation sur l'OCR Cloud Vision pour connaître la différence entre les deux cas d'utilisation.Swift
let requestData = [ "image": ["content": base64encodedImage], "features": ["type": "TEXT_DETECTION"], "imageContext": ["languageHints": ["en"]] ]
Objective-C
NSDictionary *requestData = @{ @"image": @{@"content": base64encodedImage}, @"features": @{@"type": @"TEXT_DETECTION"}, @"imageContext": @{@"languageHints": @[@"en"]} };
Enfin, appelez la fonction :
Swift
do { let result = try await functions.httpsCallable("annotateImage").call(requestData) print(result) } catch { 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] } // ... } }
Objective-C
[[_functions HTTPSCallableWithName:@"annotateImage"] callWithObject:requestData completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) { if (error) { if ([error.domain isEqualToString:@"com.firebase.functions"]) { FIRFunctionsErrorCode code = error.code; NSString *message = error.localizedDescription; NSObject *details = error.userInfo[@"details"]; } // ... } // Function completed succesfully // Get information about labeled objects }];
3. Extraire du texte à partir de blocs de texte reconnus
Si l'opération de reconnaissance de texte réussit, une réponse JSON de BatchAnnotateImagesResponse sera renvoyée dans le résultat de la tâche. Les annotations de texte se trouvent dans l'objet fullTextAnnotation
.
Vous pouvez obtenir le texte reconnu sous forme de chaîne dans le champ text
. Exemple :
Swift
let annotation = result.flatMap { $0.data as? [String: Any] }
.flatMap { $0["fullTextAnnotation"] }
.flatMap { $0 as? [String: Any] }
guard let annotation = annotation else { return }
if let text = annotation["text"] as? String {
print("Complete annotation: \(text)")
}
Objective-C
NSDictionary *annotation = result.data[@"fullTextAnnotation"];
if (!annotation) { return; }
NSLog(@"\nComplete annotation:");
NSLog(@"\n%@", annotation[@"text"]);
Vous pouvez également obtenir des informations spécifiques à des régions de l'image. Pour chaque block
, paragraph
, word
et symbol
, vous pouvez obtenir le texte reconnu dans la région et les coordonnées du cadre de sélection de la région. Exemple :
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
}
}
Objective-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];
}
}