Apple প্ল্যাটফর্মে Firebase Auth ও Functions ব্যবহার করে Cloud Vision-এর মাধ্যমে নিরাপদে ছবির টেক্সট শনাক্ত করা

আপনার অ্যাপ থেকে Google Cloud API কল করতে, আপনাকে একটি ইন্টারমিডিয়েট REST API তৈরি করতে হবে যা অনুমোদন ম্যানেজ করে এবং API কী-এর মতো গোপন ভ্যালু সুরক্ষিত রাখে। তারপর, এই মধ্যবর্তী পরিষেবার সাথে যোগাযোগ ও যাচাই করার জন্য আপনার মোবাইল অ্যাপে কোড লিখতে হবে।

এই REST API তৈরি করার একটি উপায় হল Firebase Authentication এবং Functions ব্যবহার করা, যা আপনাকে Google Cloud API-এর জন্য একটি ম্যানেজ করা, সার্ভারলেস গেটওয়ে প্রদান করে। এটি যাচাইকরণ ম্যানেজ করে এবং আপনার মোবাইল অ্যাপ থেকে প্রি-বিল্ট SDK-এর মাধ্যমে কল করা যেতে পারে।

এই নির্দেশিকা দেখায় যে কীভাবে আপনার অ্যাপ থেকে Cloud Vision API কল করার জন্য এই টেকনিক ব্যবহার করতে হয়। এই পদ্ধতিটি সমস্ত যাচাইকৃত ব্যবহারকারীকে আপনার Cloud প্রোজেক্টের মাধ্যমে Cloud Vision বিল করা পরিষেবা অ্যাক্সেস করার অনুমতি দেবে, তাই এগিয়ে যাওয়ার আগে এই যাচাইকরণ পদ্ধতিটি আপনার ব্যবহারের ক্ষেত্রে যথেষ্ট কিনা তা বিবেচনা করুন।

শুরু করার আগে

আপনার প্রোজেক্ট কনফিগার করুন

আপনি যদি এখনও আপনার অ্যাপে Firebase যোগ না করে থাকেন, তাহলে শুরু করার নির্দেশিকা-তে দেওয়া ধাপগুলি অনুসরণ করে তা করুন।

Firebase ডিপেন্ডেন্সি ইনস্টল ও ম্যানেজ করতে Swift প্যাকেজ ম্যানেজার ব্যবহার করুন।

  1. Xcode-এ, আপনার অ্যাপ প্রোজেক্ট খোলা রেখে, ফাইল > প্যাকেজ যোগ করুন বিকল্পে নেভিগেট করুন।
  2. প্রম্পট করা হলে, Firebase Apple প্ল্যাটফর্ম SDK রিপোজিটরি যোগ করুন:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Firebase ML লাইব্রেরি বেছে নিন।
  5. আপনার টার্গেটের বিল্ড সেটিংসের অন্যান্য লিঙ্কার ফ্ল্যাগ বিভাগে -ObjC ফ্ল্যাগ যোগ করুন।
  6. হয়ে গেলে, Xcode অটোমেটিক ব্যাকগ্রাউন্ডে আপনার ডিপেন্ডেন্সি সমাধান ও ডাউনলোড করা শুরু করবে।

এরপর, অ্যাপ-মধ্যস্থ কিছু সেট-আপ করুন:

  1. আপনার অ্যাপে, Firebase ইম্পোর্ট করুন:

    Swift

    import FirebaseMLModelDownloader

    Objective-C

    @import FirebaseMLModelDownloader;

আরও কয়েকটি কনফিগারেশন ধাপ, এবং আমরা শুরু করার জন্য প্রস্তুত:

  1. আপনার প্রোজেক্টের জন্য ক্লাউড-ভিত্তিক API চালু না করে থাকলে, এখনই তা করুন:

    1. Firebase কনসোলে Firebase ML APIs পৃষ্ঠা খুলুন।
    2. আপনি যদি আগে থেকে আপনার প্রোজেক্টকে যখন ব্যবহার করবেন তখন পেমেন্ট করুন Blaze প্রাইসিং প্ল্যানে আপগ্রেড না করে থাকেন, তাহলে তা করতে আপগ্রেড করুন বিকল্পে ক্লিক করুন। (আপনার প্রোজেক্ট Blaze প্রাইসিং প্ল্যানে না থাকলে তবেই আপনাকে আপগ্রেড করার জন্য প্রম্পট করা হবে।)

      শুধুমাত্র Blaze প্রাইসিং প্ল্যানের প্রোজেক্টই ক্লাউড-ভিত্তিক API ব্যবহার করতে পারে।

    3. ক্লাউড-ভিত্তিক API আগে থেকে চালু করা না থাকলে, ক্লাউড-ভিত্তিক API চালু করুন বিকল্পে ক্লিক করুন।
  2. Cloud Vision API-তে অ্যাক্সেস বন্ধ করতে আপনার আগে থেকে থাকা Firebase API কী কনফিগার করুন:
    1. Cloud কনসোলের ক্রেডেনশিয়াল পৃষ্ঠা খুলুন।
    2. তালিকায় থাকা প্রতিটি API কী-এর জন্য, এডিটিং ভিউ খুলুন এবং 'কী সীমাবদ্ধতা' বিভাগে, Cloud Vision API বাদ দিয়ে উপলভ্য সব API তালিকায় যোগ করুন।

কল করা যায় এমন ফাংশন ডিপ্লয় করুন

এরপর, আপনার অ্যাপ ও Cloud Vision API-এর মধ্যে সংযোগ স্থাপন করতে আপনি যে ক্লাউড ফাংশন ব্যবহার করবেন সেটি ডিপ্লয় করুন। functions-samples রিপোজিটরিতে একটি উদাহরণ রয়েছে যা আপনি ব্যবহার করতে পারবেন।

ডিফল্ট হিসেবে, এই ফাংশনের মাধ্যমে Cloud Vision API অ্যাক্সেস করলে, আপনার অ্যাপের শুধুমাত্র যাচাই করা ব্যবহারকারীরাই Cloud Vision API অ্যাক্সেস করতে পারবেন। আপনি বিভিন্ন প্রয়োজনীয়তার জন্য ফাংশনটি পরিবর্তন করতে পারেন।

ফাংশন ডিপ্লয় করতে:

  1. functions-samples repo ক্লোন বা ডাউনলোড করুন এবং Node-1st-gen/vision-annotate-image ডিরেক্টরিতে পরিবর্তন করুন:
    git clone https://github.com/firebase/functions-samples
    cd Node-1st-gen/vision-annotate-image
    
  2. ডিপেন্ডেন্সি ইনস্টল করুন:
    cd functions
    npm install
    cd ..
  3. আপনার কাছে Firebase CLI না থাকলে, এটি ইনস্টল করুন।
  4. vision-annotate-image ডিরেক্টরিতে Firebase প্রোজেক্ট শুরু করুন। প্রম্পট করা হলে, তালিকা থেকে আপনার প্রোজেক্ট বেছে নিন।
    firebase init
  5. ফাংশন ডিপ্লয় করুন:
    firebase deploy --only functions:annotateImage

আপনার অ্যাপে Firebase Auth যোগ করা

উপরে ডিপ্লয় করা কল করা যায় এমন ফাংশন আপনার অ্যাপের যাচাই না করা ব্যবহারকারীদের থেকে আসা যেকোনও অনুরোধ বাতিল করে দেবে। আপনি যদি এখনও এটি না করে থাকেন, তাহলে আপনাকে আপনার অ্যাপে Firebase Auth যোগ করতে হবে।

আপনার অ্যাপে প্রয়োজনীয় ডিপেন্ডেন্সি যোগ করুন

Firebase লাইব্রেরির জন্য Cloud Functions ইনস্টল করতে Swift Package Manager ব্যবহার করুন।

এখন আপনি ছবিতে টেক্সট শনাক্ত করা শুরু করার জন্য প্রস্তুত।

১. ইনপুট ছবি প্রস্তুত করুন

Cloud Vision কল করার জন্য, ছবিটিকে অবশ্যই base64-এনকোডেড স্ট্রিং হিসেবে ফর্ম্যাট করতে হবে। UIImage প্রসেস করতে:

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

২. টেক্সট শনাক্ত করার জন্য কল করা যায় এমন ফাংশন চালু করুন

কোনও ছবিতে ল্যান্ডমার্ক শনাক্ত করতে, JSON Cloud Vision অনুরোধ পাস করে কল করা যায় এমন ফাংশন ইনভোক করুন।

  1. প্রথমে, Cloud Functions-এর একটি ইনস্ট্যান্স ইনিশিয়ালাইজ করুন:

    Swift

    lazy var functions = Functions.functions()
    

    Objective-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. অনুরোধ তৈরি করুন। Cloud Vision API-তে দুই ধরনের টেক্সট শনাক্তকরণ কাজ করে: TEXT_DETECTION এবং DOCUMENT_TEXT_DETECTION। দুটি ব্যবহারের ক্ষেত্রের মধ্যে পার্থক্য জানতে Cloud Vision OCR ডকুমেন্ট দেখুন।

    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. শেষে, ফাংশনটি ইনভোক করুন:

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

৩. শনাক্ত করা টেক্সটের ব্লক থেকে টেক্সট এক্সট্র্যাক্ট করুন

টেক্সট শনাক্তকরণ অপারেশন সফল হলে, টাস্কের ফলাফলে BatchAnnotateImagesResponse-এর JSON রেসপন্স ফেরত পাঠানো হবে। টেক্সট অ্যানোটেশন fullTextAnnotation অবজেক্টে পাওয়া যাবে।

আপনি text ফিল্ডে স্ট্রিং হিসেবে শনাক্ত করা টেক্সট পেতে পারেন। যেমন:

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

এছাড়াও, আপনি ছবির নির্দিষ্ট অঞ্চল সম্পর্কে তথ্য পেতে পারেন। প্রতিটি block, paragraph, word ও symbol-এর জন্য, আপনি অঞ্চলে শনাক্ত করা টেক্সট এবং অঞ্চলের বাউন্ডিং কোঅর্ডিনেট পেতে পারেন। যেমন:

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