Apple platformlarında Firebase Auth ve Functions kullanarak Cloud Vision ile Görüntülerdeki Metni Güvenle Tanıyın

Uygulamanızdan bir Google Cloud API'sini ç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 hizmette kimlik doğrulaması yapmak ve iletişim kurmak için mobil uygulamanıza kod yazmanız gerekir.

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

Bu kılavuz, uygulamanızdan Cloud Vision API'yi çağırmak için bu tekniğin nasıl kullanılacağını gösterir. Bu yöntem, kimliği doğrulanmış tüm kullanıcıların Bulut projeniz aracılığıyla Cloud Vision faturalı hizmetlere erişmesine izin verecektir; bu nedenle, devam etmeden önce bu kimlik doğrulama mekanizmasının kullanım durumunuz için yeterli olup olmadığını düşünün.

Sen başlamadan önce

Projenizi yapılandırın

Zaten uygulamanıza Firebase eklemediyseniz, adımları izleyerek bunu başlangıç kılavuzuna .

Firebase bağımlılıklarını kurmak ve yönetmek için Swift Paket Yöneticisi'ni kullanın.

  1. Xcode olarak, uygulama açma projesi, gezinilebilen ile Dosya> Swift Paketleri> Paket Bağımlılık Ekle.
  2. İstendiğinde, Firebase Apple platformları SDK deposunu ekleyin:
  3.   https://github.com/firebase/firebase-ios-sdk
      
  4. Firebase ML kitaplığını seçin.
  5. Bittiğinde, Xcode otomatik olarak bağımlılıklarınızı arka planda çözmeye ve indirmeye başlayacaktır.

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

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

    Süratli

    import Firebase

    Amaç-C

    @import Firebase;

Birkaç yapılandırma adımı daha ve başlamaya hazırız:

  1. Projeniz için Bulut tabanlı API'leri henüz etkinleştirmediyseniz, şimdi yapın:

    1. Firebase ML API'leri sayfasını Firebase konsolunun.
    2. Zaten Blaze fiyatlandırma planına projenizi yükseltmediyseniz, bunu Yükselt tıklayın. (Yalnızca projeniz Blaze planında değilse yükseltme yapmanız istenir.)

      Yalnızca Blaze düzeyindeki projeler Bulut tabanlı API'leri kullanabilir.

    3. Bulut tabanlı API'ler zaten etkin değilse, tık Bulut tabanlı API'leri etkinleştirin.
  2. Cloud Vision API'ye erişime izin vermemek için mevcut Firebase API anahtarlarınızı yapılandırın:
    1. Kimlik Bulut konsolunun sayfasını.
    2. Listedeki her API anahtarı için, düzenleme görünümünü açmak ve Anahtar Kısıtlamalar bölümünde listeye Bulut Vision API haricinde mevcut API'leri tümünü ekleyin.

Çağrılabilir işlevi dağıtın

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

Varsayılan olarak, bu işlev aracılığıyla Cloud Vision API'ye erişmek, yalnızca uygulamanızın kimliği doğrulanmış kullanıcılarının Cloud Vision API'ye erişmesine izin verir. Fonksiyonu farklı gereksinimler için değiştirebilirsiniz.

İşlevi dağıtmak için:

  1. Klon veya indirme fonksiyonları-numuneler repo ve değişim vision-annotate-image dizinine:
    git clone https://github.com/firebase/functions-samples
    cd vision-annotate-image
    
  2. Bağımlılıkları yükleyin:
    cd functions
    npm install
    cd ..
    
  3. Eğer Firebase CLI yoksa, yükleyin .
  4. Bir Firebase projeyi başlat vision-annotate-image dizininde. İstendiğinde, listeden projenizi seçin.
    firebase init
  5. İşlevini dağıtın:
    firebase deploy --only functions:annotateImage

Uygulamanıza Firebase Auth'u 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 reddedecektir. Şimdiye kadar yapmadıysanız, sen gerekir uygulamanıza Firebase Auth ekleyin.

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

Firebase kitaplığı için Cloud Functions'ı yüklemek için Swift Paket Yöneticisi'ni kullanın.

Artık resimlerdeki metni tanımaya başlamaya hazırsınız.

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

Cloud Vision'ı çağırmak için görüntünün base64 ile kodlanmış bir dize olarak biçimlendirilmesi gerekir. Bir işlemek için UIImage :

Süratli

guard let imageData = uiImage.jpegData(compressionQuality: 1.0f) else { return }
let base64encodedImage = imageData.base64EncodedString()

Amaç-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 resimde işaretlerini tanımak için, yoldan geçen bir çağrılabilir işlevi çağırmak JSON Bulut Vision isteği .

  1. İlk olarak, bir Cloud Functions örneğini başlatın:

    Süratli

    lazy var functions = Functions.functions()
    

    Amaç-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. İsteği oluşturun. Bulut Vision API iki destekler Türleri : Metin algılama TEXT_DETECTION ve DOCUMENT_TEXT_DETECTION . Bkz Bulut Vizyon OCR Dokümanlar iki kullanım durumları arasındaki farkın.

    Süratli

    let requestData = [
      "image": ["content": base64encodedImage],
      "features": ["type": "TEXT_DETECTION"],
      "imageContext": ["languageHints": ["en"]]
    ]
    

    Amaç-C

    NSDictionary *requestData = @{
      @"image": @{@"content": base64encodedImage},
      @"features": @{@"type": @"TEXT_DETECTION"},
      @"imageContext": @{@"languageHints": @[@"en"]}
    };
    
  3. Son olarak, işlevi çağırın:

    Süratli

    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
    }
    

    Amaç-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. Tanınan metin bloklarından metin ayıklayın

Metin tanıma işlemi başarılı olursa, bir JSON yanıtı BatchAnnotateImagesResponse görevin sonucu döndürülür. Metin ek açıklamaları bulunabilir fullTextAnnotation nesne.

Sen bir dize olarak tanınan metni alabilirsiniz text alanına. Örneğin:

Süratli

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

Amaç-C

NSDictionary *annotation = result.data[@"fullTextAnnotation"];
if (!annotation) { return; }
NSLog(@"\nComplete annotation:");
NSLog(@"\n%@", annotation[@"text"]);

Ayrıca görüntünün bölgelerine özel bilgiler de alabilirsiniz. Her biri için block , paragraph , word ve symbol , bölgenin en tanınmış metin ve bölgenin sınırlayıcı koordinatlarını alabilirsiniz. Örneğin:

Süratli

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
}

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