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

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

Bu REST API'yi oluşturmanın bir yolu da Firebase Authentication and Functions'ı kullanmaktır. Firebase Authentication and Functions, kimlik doğrulamayı gerçekleştiren ve önceden oluşturulmuş SDK'larla mobil uygulamanızdan çağrılabilen, Google Cloud API'lerine yönetilen, sunucusuz bir ağ geçidi sağlar.

Bu kılavuzda, uygulamanızdan Cloud Vision API'yi çağırmak için bu tekniğin nasıl kullanılacağı gösterilmektedir. Bu yöntem, kimliği doğrulanmış tüm kullanıcıların Cloud projeniz üzerinden Cloud Vision tarafından faturalandırılan hizmetlere 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ı düşünün.

Başlamadan önce

Projenizi yapılandırın

Uygulamanıza henüz Firebase'i eklemediyseniz başlangıç kılavuzundaki adımları uygulayarak bunu yapabilirsiniz.

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

  1. Xcode'da, uygulamanız 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ındaki Diğer Bağlayıcı İşaretleri bölümüne ekleyin.
  6. İşlem tamamlandığında Xcode, arka planda bağımlılıklarınızı otomatik olarak çözümlemeye ve indirmeye başlar.

Sonra, bazı uygulama içi kurulum işlemleri 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ı daha tamamladıktan sonra başlamaya hazırız:

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

    1. Firebase konsolunun Firebase ML API'leri sayfasını açın.
    2. Projenizi daha önce Blaze fiyatlandırma planına yükseltmediyseniz Yükselt'i tıklayarak yükseltme yapabilirsiniz. (Yalnızca projeniz Blaze planında değilse yükseltme yapmanız istenir.)

      Bulut tabanlı API'ler yalnızca Blaze düzeyindeki projelerde kullanılabilir.

    3. Cloud tabanlı API'ler henüz etkinleştirilmemişse Cloud tabanlı API'leri etkinleştir'i tıklayın.
  2. Mevcut Firebase API anahtarlarınızı, Cloud Vision API'ye erişime izin vermeyecek ş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 haricindeki tüm mevcut 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 deposu, kullanabileceğiniz bir örnek içerir.

Varsayılan olarak, Cloud Vision API'ye bu işlev üzerinden erişmek, yalnızca uygulamanızın kimliği doğrulanmış kullanıcılarının Cloud Vision API'ye erişmesine izin verir. İşlevi farklı şartlara göre değiştirebilirsiniz.

İşlevi dağıtmak için:

  1. functions-samples depoyu 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

Firebase Auth'u uygulamanıza ekleyin

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 uygulamanıza Firebase Auth'u eklemeniz gerekir.

Gerekli bağımlılıkları uygulamanıza ekleyin

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

Artık resimlerdeki metinleri tanımaya hazırsınız.

1. Giriş resmini hazırlama

Cloud Vision'ı çağırmak için görüntünün base64 kodlu bir dize olarak biçimlendirilmelidir. Bir UIImage öğesini 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ğırın

Bir görüntüdeki önemli noktaları tanımak için bir JSON Cloud Vision isteği ileterek çağrılabilir işlevi çağırın.

  1. Öncelikle, bir Cloud Functions ö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 Belgeleri'ne 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ındaki metni ayıkla

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ı fullTextAnnotation nesnesinde bulunabilir.

Tanınan metni text alanında dize olarak alabilirsiniz. Örnek:

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

Resmin belirli bölgelerine özel bilgileri de alabilirsiniz. Her block, paragraph, word ve symbol için bölgede tanınan metin ve bölgenin sınırlayıcı koordinatlarını alabilirsiniz. Örnek:

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