アプリからGoogleCloudAPIを呼び出すには、承認を処理し、APIキーなどのシークレット値を保護する中間RESTAPIを作成する必要があります。次に、この中間サービスを認証して通信するために、モバイルアプリにコードを記述する必要があります。
このRESTAPIを作成する1つの方法は、Firebase Authentication and Functionsを使用することです。これにより、認証を処理し、ビルド済みのSDKを使用してモバイルアプリから呼び出すことができる、GoogleCloudAPIへの管理されたサーバーレスゲートウェイが提供されます。
このガイドでは、この手法を使用してアプリからCloudVisionAPIを呼び出す方法を示します。この方法では、認証されたすべてのユーザーがCloudプロジェクトを介してCloud Visionの課金サービスにアクセスできるようになるため、先に進む前に、この認証メカニズムがユースケースに十分かどうかを検討してください。
あなたが始める前に
プロジェクトを構成する
まだFirebaseをアプリに追加していない場合は、スタートガイドの手順に従って追加してください。Swift Package Managerを使用して、Firebaseの依存関係をインストールおよび管理します。
- Xcodeで、アプリプロジェクトを開いた状態で、 [ファイル]>[パッケージの追加]に移動します。
- プロンプトが表示されたら、FirebaseAppleプラットフォームSDKリポジトリを追加します。
- FirebaseMLライブラリを選択します。
- 完了すると、Xcodeは自動的に依存関係の解決とダウンロードをバックグラウンドで開始します。
https://github.com/firebase/firebase-ios-sdk
次に、アプリ内セットアップを実行します。
- アプリで、Firebaseをインポートします。
迅速
import FirebaseMLModelDownloader
Objective-C
@import FirebaseMLModelDownloader;
さらにいくつかの構成手順を実行すると、準備が整います。
プロジェクトでクラウドベースのAPIをまだ有効にしていない場合は、今すぐ有効にしてください。
- FirebaseコンソールのFirebaseMLAPIページを開きます。
プロジェクトをまだBlaze料金プランにアップグレードしていない場合は、[アップグレード]をクリックしてアップグレードします。 (プロジェクトがBlazeプランに含まれていない場合にのみ、アップグレードするように求められます。)
BlazeレベルのプロジェクトのみがクラウドベースのAPIを使用できます。
- クラウドベースのAPIがまだ有効になっていない場合は、[クラウドベースのAPIを有効にする]をクリックします。
- CloudVisionAPIへのアクセスを禁止するように既存のFirebaseAPIキーを構成します。
- クラウドコンソールの[資格情報]ページを開きます。
- リスト内のAPIキーごとに、編集ビューを開き、[キーの制限]セクションで、CloudVisionAPIを除く使用可能なすべてのAPIをリストに追加します。
呼び出し可能な関数をデプロイする
次に、アプリとCloudVisionAPIのブリッジに使用するCloudFunctionをデプロイします。 functions-samples
リポジトリには、使用できる例が含まれています。
デフォルトでは、この関数を介してCloud Vision APIにアクセスすると、アプリの認証されたユーザーのみがCloudVisionAPIにアクセスできます。さまざまな要件に合わせて関数を変更できます。
関数をデプロイするには:
- 関数のクローンを作成するかダウンロードします-サンプルリポジトリを作成し、
vision-annotate-image
ディレクトリに変更します:git clone https://github.com/firebase/functions-samples
cd vision-annotate-image
- インストールの依存関係:
cd functions
npm install
cd ..
- Firebase CLIをお持ちでない場合は、インストールしてください。
-
vision-annotate-image
ディレクトリでFirebaseプロジェクトを初期化します。プロンプトが表示されたら、リストからプロジェクトを選択します。firebase init
- 関数をデプロイします:
firebase deploy --only functions:annotateImage
アプリにFirebaseAuthを追加する
上記でデプロイされた呼び出し可能関数は、アプリの認証されていないユーザーからのリクエストを拒否します。まだ行っていない場合は、FirebaseAuthをアプリに追加する必要があります。
アプリに必要な依存関係を追加する
Swift Package Managerを使用して、Cloud FunctionsforFirebaseライブラリをインストールします。
これで、画像内のテキストの認識を開始する準備が整いました。
1.入力画像を準備します
Cloud Visionを呼び出すには、画像をbase64でエンコードされた文字列としてフォーマットする必要があります。UIImage
を処理するには:迅速
guard let imageData = uiImage.jpegData(compressionQuality: 1.0f) else { return } let base64encodedImage = imageData.base64EncodedString()
Objective-C
NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f); NSString *base64encodedImage = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
2.呼び出し可能関数を呼び出してテキストを認識します
画像内のランドマークを認識するには、JSONCloudVisionリクエストを渡して呼び出し可能な関数を呼び出します。まず、CloudFunctionsのインスタンスを初期化します。
迅速
lazy var functions = Functions.functions()
Objective-C
@property(strong, nonatomic) FIRFunctions *functions;
リクエストを作成します。 Cloud Vision APIは、
TEXT_DETECTION
とDOCUMENT_TEXT_DETECTION
の2種類のテキスト検出をサポートしています。 2つのユースケースの違いについては、 CloudVisionOCRドキュメントを参照してください。迅速
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"]} };
最後に、関数を呼び出します。
迅速
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 }
Objective-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.認識されたテキストのブロックからテキストを抽出します
テキスト認識操作が成功すると、 BatchAnnotateImagesResponseのJSON応答がタスクの結果に返されます。テキスト注釈は、 fullTextAnnotation
オブジェクトにあります。
認識されたテキストをtext
フィールドの文字列として取得できます。例えば:
迅速
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)")
Objective-C
NSDictionary *annotation = result.data[@"fullTextAnnotation"];
if (!annotation) { return; }
NSLog(@"\nComplete annotation:");
NSLog(@"\n%@", annotation[@"text"]);
画像の領域に固有の情報を取得することもできます。 block
、 paragraph
、 word
、 symbol
ごとに、領域で認識されるテキストと領域の境界座標を取得できます。例えば:
迅速
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];
}
}