Apple platformlarında Firebase Auth ve Functions işlevlerini kullanarak Cloud Vision ile resimlerdeki metinleri güvenli bir şekilde tanıyın

Uygulamanızdan bir Google Cloud API'si çağırmak için yetkilendirmeyi işleyen ve API anahtarları gibi gizli değerleri koruyan bir ara REST API oluşturmanız gerekir. Ardından, bu ara hizmetle kimlik doğrulaması yapmak ve iletişim kurmak için mobil uygulamanızda kod yazmanız gerekir.

Bu REST API'yi oluşturmanın bir yolu, Firebase Authentication ve Functions'ı kullanmaktır. Bu sayede, kimlik doğrulama işlemini gerçekleştiren ve önceden oluşturulmuş SDK'larla mobil uygulamanızdan çağrılabilen, Google Cloud API'lerine yönelik yönetilen ve sunucusuz bir ağ geçidi elde edersiniz.

Bu kılavuzda, bu tekniği kullanarak uygulamanızdan Cloud Vision API'yi çağırma yöntemi gösterilmektedir. Bu yöntem, kimliği doğrulanmış tüm kullanıcıların Cloud projeniz üzerinden Cloud Vision faturalandırılan hizmetlerine erişmesine olanak tanır. Bu nedenle, devam etmeden önce bu kimlik doğrulama mekanizmasının kullanım alanınız için yeterli olup olmadığını göz önünde bulundurun.

Başlamadan önce

Projenizi yapılandırın

Firebase'i henüz uygulamanıza eklemediyseniz Başlangıç kılavuzundaki adımları uygulayarak ekleyin.

Firebase bağımlılıklarını yüklemek ve yönetmek için Swift Package Manager'ı kullanın.

  1. Xcode'da, uygulama projeniz açıkken File > Add Packages'a (Dosya > Paket Ekle) gidin.
  2. İstendiğinde Firebase Apple platformları SDK deposunu ekleyin:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Firebase ML kitaplığını seçin.
  5. -ObjC işaretini hedefinizin derleme ayarlarının Other Linker Flags (Diğer Bağlayıcı İşaretleri) bölümüne ekleyin.
  6. İşlem tamamlandığında Xcode, bağımlılıklarınızı otomatik olarak çözümlemeye ve arka planda indirmeye başlar.

Ardından, uygulama içi kurulumu gerçekleştirin:

  1. Uygulamanızda Firebase'i içe aktarın:

    Swift

    import FirebaseMLModelDownloader

    Objective-C

    @import FirebaseMLModelDownloader;

Birkaç yapılandırma adımından sonra kullanmaya başlayabilirsiniz:

  1. Projeniz için bulut tabanlı API'leri henüz etkinleştirmediyseniz şimdi etkinleştirin:

    1. Firebase konsolunda Firebase ML API'ler sayfasını açın.
    2. Projenizi henüz kullandıkça öde Blaze fiyatlandırma planına yükseltmediyseniz yükseltmek için Yükselt'i tıklayın. (Yalnızca projeniz Blaze fiyatlandırma planında değilse yükseltmeniz istenir.)

      Yalnızca Blaze fiyatlandırma planındaki projeler bulut tabanlı API'leri kullanabilir.

    3. Bulut tabanlı API'ler etkinleştirilmemişse Bulut tabanlı API'leri etkinleştir'i tıklayın.
  2. Mevcut Firebase API anahtarlarınızı Cloud Vision API'ye erişimi engelleyecek şekilde yapılandırın:
    1. Cloud Console'un Kimlik bilgileri sayfasını açın.
    2. Listedeki her API anahtarı için düzenleme görünümünü açın ve Anahtar Kısıtlamaları bölümünde, Cloud Vision API hariç tüm kullanılabilir API'leri listeye ekleyin.

Çağrılabilir işlevi dağıtma

Ardından, uygulamanız ile Cloud Vision API arasında köprü oluşturmak için kullanacağınız Cloud Functions işlevini dağıtın. functions-samples deposunda kullanabileceğiniz bir örnek bulunur.

Bu işlev aracılığıyla Cloud Vision API'ye erişildiğinde, varsayılan olarak yalnızca uygulamanızın kimliği doğrulanmış kullanıcıları Cloud Vision API'ye erişebilir. İşlevi farklı gereksinimlere göre değiştirebilirsiniz.

İşlevi dağıtmak için:

  1. functions-samples deposunu klonlayın veya indirin ve Node-1st-gen/vision-annotate-image dizinine geçin:
    git clone https://github.com/firebase/functions-samples
    cd Node-1st-gen/vision-annotate-image
    
  2. Bağımlılıkları yükleyin:
    cd functions
    npm install
    cd ..
  3. Firebase CLI'nız yoksa yükleyin.
  4. vision-annotate-image dizininde bir Firebase projesi başlatın. İstendiğinde listeden projenizi seçin.
    firebase init
  5. İşlevi dağıtın:
    firebase deploy --only functions:annotateImage

Uygulamanıza Firebase Auth'u ekleme

Yukarıda dağıtılan çağrılabilir işlev, uygulamanızın kimliği doğrulanmamış kullanıcılarından gelen tüm istekleri reddeder. Henüz yapmadıysanız Firebase Auth'u uygulamanıza eklemeniz gerekir.

Uygulamanıza gerekli bağımlılıkları ekleyin

Firebase için Cloud Functions kitaplığını yüklemek üzere Swift Package Manager'ı kullanın.

Artık resimlerdeki metinleri tanımaya başlayabilirsiniz.

1. Giriş görüntüsünü hazırlama

Cloud Vision'ı çağırmak için resmin base64 kodlu dize olarak biçimlendirilmesi gerekir. UIImage işlemek için:

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. Metni tanımak için çağrılabilir işlevi çağırma

Bir resimdeki önemli noktaları tanımak için JSON Cloud Vision isteği ileterek çağrılabilir işlevi çağırın.

  1. Öncelikle Cloud Functions'ın bir örneğini başlatın:

    Swift

    lazy var functions = Functions.functions()
    

    Objective-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. İsteği oluşturun. Cloud Vision API, iki Tür metin algılamayı destekler: TEXT_DETECTION ve DOCUMENT_TEXT_DETECTION. İki kullanım alanı arasındaki fark için Cloud Vision OCR belgelerine bakın.

    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"]}
    };
    
  3. Son olarak, işlevi çağırın:

    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. Tanınan metin bloklarından metin çıkarma

Metin tanıma işlemi başarılı olursa görevin sonucunda BatchAnnotateImagesResponse JSON yanıtı döndürülür. Metin ek açıklamalarını fullTextAnnotation nesnesinde bulabilirsiniz.

Tanınan metni text alanında dize olarak alabilirsiniz. Örneğin:

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"]);

Ayrıca, resmin belirli bölgeleriyle ilgili bilgi de alabilirsiniz. block, paragraph, word ve symbol için metnin bölgede tanınmasını ve bölgenin sınırlayıcı koordinatlarını alabilirsiniz. Örneğin:

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];
  }
}