لطلب واجهة برمجة تطبيقات Google Cloud من تطبيقك، يجب إنشاء واجهة برمجة تطبيقات وسيطة واجهة برمجة تطبيقات REST التي تعالج التفويض وتحمي القيم السرية، مثل مفاتيح واجهة برمجة التطبيقات. يجب بعد ذلك كتابة رمز في تطبيق الأجهزة الجوّالة للمصادقة على هذه الخدمة الوسيطة والتواصل معها.
إحدى الطرق لإنشاء واجهة برمجة تطبيقات REST هذه هي باستخدام مصادقة ووظائف Firebase، التي تمنحك مدخلاً مُدارًا بدون خادم إلى واجهات Google Cloud APIs التي تعالج المصادقة ويمكن طلبها من تطبيقك للأجهزة الجوّالة باستخدام SDK المنشأة مسبقًا.
يوضِّح هذا الدليل كيفية استخدام هذا الأسلوب لطلب بيانات Cloud Vision API من تطبيقك. ستسمح هذه الطريقة لجميع المستخدمين الذين تمت مصادقتهم بالوصول إلى الخدمات التي تتم فوترتها عبر Cloud Vision من خلال مشروعك على Google Cloud، وبالتالي قبل المتابعة، تحقَّق مما إذا كانت آلية المصادقة هذه كافية لحالة الاستخدام لديك.
قبل البدء
ضبط مشروعك
إذا لم يسبق لك إضافة Firebase إلى تطبيقك، يمكنك إجراء ذلك من خلال اتّباع الخطوات الأولى في دليل البدء.يمكنك استخدام "مدير حزم Swift" لتثبيت اعتماديات Firebase وإدارتها.
- في Xcode، انتقِل إلى File (ملف) > بعد فتح مشروع التطبيق الخاص بك. إضافة حِزم
- أضِف مستودع حزمة تطوير البرامج (SDK) لمنصّات Firebase Apple عندما يُطلب منك ذلك:
- اختَر مكتبة "Firebase ML".
- أضِف العلامة
-ObjC
إلى القسم علامات الروابط الأخرى في إعدادات إصدار هدفك. - عند الانتهاء، سيبدأ Xcode تلقائيًا في حل وتنزيل ملف والتبعيات في الخلفية.
https://github.com/firebase/firebase-ios-sdk.git
بعد ذلك، يمكنك إجراء بعض الإعدادات داخل التطبيق:
- في تطبيقك، استورد Firebase:
Swift
import FirebaseMLModelDownloader
Objective-C
@import FirebaseMLModelDownloader;
في ما يلي بعض خطوات الضبط الإضافية، ونحن جاهزون لبدء الاستخدام:
-
إذا لم يسبق لك تفعيل واجهات برمجة التطبيقات المستنِدة إلى السحابة الإلكترونية لمشروعك، يُرجى إجراء ذلك الآن:
- افتح Firebase ML. صفحة واجهات برمجة التطبيقات لوحدة تحكُّم Firebase.
-
إذا لم تكن قد أجريت ترقية لمشروعك إلى خطة أسعار Blaze، انقر على يجب الترقية لإجراء ذلك. (ستتم مطالبتك بالترقية فقط إذا كان مشروعك ليس على خطة Blaze).
يمكن للمشروعات على مستوى Blaze فقط استخدام واجهات برمجة التطبيقات المستنِدة إلى السحابة الإلكترونية.
- إذا لم تكن واجهات برمجة التطبيقات المستنِدة إلى السحابة الإلكترونية مُفعَّلة، انقر على تفعيل البيانات المستندة إلى السحابة الإلكترونية. API.
- ضبط مفاتيح واجهة برمجة التطبيقات الحالية في Firebase لمنع الوصول إلى السحابة الإلكترونية
واجهة Vision API:
- افتح صفحة بيانات الاعتماد في Cloud Console.
- لكل مفتاح واجهة برمجة تطبيقات في القائمة، افتح عرض التعديل، وفي قسم "المفتاح" قسم "القيود"، أضِف جميع واجهات برمجة التطبيقات المتاحة باستثناء Cloud Vision. واجهة برمجة التطبيقات إلى القائمة.
نشر الدالة القابلة للاستدعاء
بعد ذلك، انشر وظيفة السحابة الإلكترونية التي ستستخدمها للربط بين تطبيقك والسحابة الإلكترونية
Vision API يحتوي مستودع functions-samples
على مثال
التي يمكنك استخدامها.
سيتيح الوصول إلى Cloud Vision API من خلال هذه الوظيفة تلقائيًا وصول المستخدمين الذين تمت مصادقتهم على تطبيقك إلى Cloud Vision API فقط يمكنك الدالة وفقًا للمتطلبات المختلفة.
لنشر الدالة:
- استنساخ مستودع نماذج الدوال أو نزِّله.
والتغيير إلى الدليل
Node-1st-gen/vision-annotate-image
:git clone https://github.com/firebase/functions-samples
cd Node-1st-gen/vision-annotate-image
- ثبِّت التبعيّات:
cd functions
npm install
cd ..
- إذا لم يكن لديك واجهة سطر الأوامر في Firebase، عليك تثبيته.
- إعداد مشروع Firebase في
vision-annotate-image
الدليل. اختَر مشروعك من القائمة عندما يُطلب منك ذلك.firebase init
- نشر الدالة:
firebase deploy --only functions:annotateImage
إضافة مصادقة Firebase إلى تطبيقك
سترفض الدالة القابلة للاستدعاء المنشورة أعلاه أي طلب من الحسابات التي لم تتم مصادقتها مستخدمي تطبيقك. عليك إضافة Firebase في حال لم يسبق لك إجراء ذلك. عليك المصادقة على تطبيقك.
أضف التبعيات اللازمة إلى تطبيقك
استخدِم Swift Package Manager لتثبيت "وظائف السحابة الإلكترونية لمكتبة Firebase".
أنت الآن جاهز لبدء التعرف على النص في الصور.
1- تحضير صورة الإدخال
لاستدعاء 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];
2- استدعاء الدالة القابلة للاستدعاء للتعرّف على النص
للتعرف على المعالم في صورة، استدعِ الدالة القابلة للاستدعاء وتجتاز طلب JSON Cloud Visionأولاً، عليك إعداد مثيل من دوال السحابة:
Swift
lazy var functions = Functions.functions()
Objective-C
@property(strong, nonatomic) FIRFunctions *functions;
أنشئ الطلب. تدعم Cloud Vision API نوعَين. ميزة رصد النص:
TEXT_DETECTION
وDOCUMENT_TEXT_DETECTION
. الاطّلاع على مستندات OCR في Cloud Vision لمعرفة الفرق بين حالتي الاستخدام.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"]} };
أخيرًا، استدعِ الدالة:
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- استخراج النص من مجموعات النصوص التي تم التعرّف عليها
إذا نجحت عملية التعرّف على النص، ستُطرح استجابة JSON
BatchAnnotateImagesResponse
في نتيجة المهمة. يمكن العثور على التعليقات التوضيحية النصية في
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];
}
}