![Lesson 49 How to extract text from images in python كيف تستخرج نص من الصور فى بايثون](https://i.ytimg.com/vi/n9k6f0kfP1U/hqdefault.jpg)
المحتوى
- على الجهاز أو في السحابة؟
- إنشاء تطبيق التعرف على النص مع ML Kit
- قم بتنزيل نماذج Google للتعلم الآلي المدربة مسبقًا
- بناء التصميم
- رموز شريط الإجراءات: بدء تشغيل تطبيق المعرض
- معالجة طلبات الأذونات والنقر فوق الأحداث
- تغيير حجم الصور باستخدام createTempFile
- اضبط الصورة على ImageView
- تدريس تطبيق للتعرف على النص
- اختبار المشروع
- تغليف
يمكنك أيضًا استخدام واجهة برمجة تطبيقات التعرف على النص كأساس لتطبيقات الترجمة أو خدمات إمكانية الوصول حيث يمكن للمستخدم توجيه الكاميرا الخاصة بهم إلى أي نص يكافحون معه ، وقراءته بصوت عالٍ لهم.
في هذا البرنامج التعليمي ، سنضع الأساس لمجموعة واسعة من الميزات المبتكرة ، من خلال إنشاء تطبيق يمكنه استخراج نص من أي صورة في معرض المستخدم. على الرغم من أننا لن نغطيها في هذا البرنامج التعليمي ، يمكنك أيضًا التقاط نص من محيط المستخدم في الوقت الفعلي ، عن طريق توصيل هذا التطبيق بكاميرا الجهاز.
على الجهاز أو في السحابة؟
تتوفر بعض واجهات برمجة تطبيقات ML Kit على الجهاز فقط ، ولكن بعضها متاح على الجهاز وفي السحابة ، بما في ذلك واجهة التعرف على النص.
يمكن لواجهة برمجة التطبيقات النصية المستندة إلى مجموعة النظراء تحديد نطاق أوسع من اللغات والأحرف ، كما تعد بدقة أكبر من نظيرها على الجهاز. ومع ذلك ، فإنه هل تتطلب اتصال إنترنت نشطًا ، وهو متاح فقط للمشاريع على مستوى Blaze.
في هذه المقالة ، سنشغل واجهة برمجة تطبيقات التعرف على النص محليًا ، لذلك يمكنك المتابعة بغض النظر عما إذا كنت قد قمت بالترقية إلى Blaze ، أو كنت على خطة Firebase Spark المجانية.
إنشاء تطبيق التعرف على النص مع ML Kit
قم بإنشاء تطبيق بالإعدادات التي تختارها ، ولكن عند المطالبة ، حدد قالب "نشاط فارغ".
يعد ML Kit SDK جزءًا من Firebase ، لذلك ستحتاج إلى توصيل مشروعك بـ Firebase ، باستخدام شهادة توقيع SHA-1. للحصول على SHA-1 لمشروعك:
- حدد علامة التبويب "Gradle" في Android Studio.
- في لوحة "مشاريع Gradle" ، انقر نقرًا مزدوجًا لتوسيع "جذر" مشروعك ، ثم حدد "المهام> Android> توقيع التقرير".
- يجب تحديث اللوحة الموجودة أسفل نافذة Android Studio لعرض بعض المعلومات حول هذا المشروع - بما في ذلك شهادة توقيع SHA-1.
لتوصيل مشروعك بـ Firebase:
- في متصفح الويب الخاص بك ، قم بتشغيل Firebase Console.
- حدد "إضافة مشروع".
- أعط اسم مشروعك أنا أستخدم "اختبار ML".
- اقرأ الشروط والأحكام ، وإذا كنت سعيدًا بالمتابعة ، فحدد "أوافق ..." ثم "إنشاء مشروع".
- حدد "إضافة Firebase إلى تطبيق Android الخاص بك."
- أدخل اسم حزمة المشروع ، والذي ستجده في الجزء العلوي من ملف MainActivity ، وداخل البيان.
- أدخل شهادة توقيع SHA-1 لمشروعك.
- انقر فوق "تسجيل التطبيق".
- حدد "تنزيل google-services.json". يحتوي هذا الملف على جميع بيانات تعريف Firebase اللازمة لمشروعك ، بما في ذلك مفتاح API.
- في Android Studio ، اسحب وإسقط ملف google-services.json في دليل "تطبيق" مشروعك.
- افتح ملف build.gradle على مستوى المشروع وأضف classpath لخدمات Google:
classpath com.google.gms: google-services: 4.0.1
- افتح ملف build.gradle على مستوى التطبيق الخاص بك ، وقم بإضافة تبعيات لـ Firebase Core و Firebase ML Vision ومترجم النموذج ، بالإضافة إلى مكون خدمات Google الإضافي:
طبق المكوّن الإضافي: com.google.gms.google-services ... ... ... تبعيات {application fileTree (dir: libs، include:) application com.google.firebase: firebase-core: 16.0.1 implementation com. google.firebase: firebase-ml-vision: تطبيق 16.0.0 com.google.firebase: firebase-ml-model-phpreter: 16.0.0
في هذه المرحلة ، ستحتاج إلى تشغيل مشروعك حتى يتمكن من الاتصال بخوادم Firebase:
- قم بتثبيت تطبيقك على هاتف ذكي أو جهاز لوحي يعمل بنظام Android ، أو على جهاز Android الظاهري (AVD).
- في Firebase Console ، حدد "تشغيل التطبيق للتحقق من التثبيت".
- بعد لحظات قليلة ، سترى "مبروك" ؛ حدد "متابعة إلى وحدة التحكم."
قم بتنزيل نماذج Google للتعلم الآلي المدربة مسبقًا
بشكل افتراضي ، يقوم ML Kit بتنزيل النماذج فقط عند الحاجة إليها ، لذلك سيقوم التطبيق لدينا بتنزيل نموذج التعرف الضوئي على الحروف عندما يحاول المستخدم استخراج النص لأول مرة.
قد يكون لهذا تأثير سلبي على تجربة المستخدم - تخيل محاولة الوصول إلى ميزة ، فقط لاكتشاف أن التطبيق عليه تنزيل المزيد من الموارد قبل أن يتمكن من تقديم هذه الميزة بالفعل. في أسوأ الحالات ، قد لا يتمكن تطبيقك حتى من تنزيل الموارد التي يحتاجها ، عندما يحتاج إليها ، على سبيل المثال إذا كان الجهاز ليس لديه اتصال بالإنترنت.
للتأكد من أن هذا لا يحدث مع تطبيقنا ، سأقوم بتنزيل طراز OCR الضروري في وقت التثبيت ، والذي يتطلب بعض التغييرات على Maniest.
على الرغم من فتح "البيان" ، سأضيف أيضًا إذن WRITE_EXTERNAL_STORAGE ، الذي سنستخدمه لاحقًا في هذا البرنامج التعليمي.
بناء التصميم
دعنا نتخلص من الأشياء السهلة وننشئ نسقًا يتكون من:
- ImageView. في البداية ، سيعرض هذا عنصرًا نائبًا ، لكنه سيتم تحديثه بمجرد أن يختار المستخدم صورة من معرضه.
- زر ، والذي يؤدي إلى استخراج النص.
- عرض نص ، حيث سنقوم بعرض النص المستخرج.
- ScrollView. نظرًا لعدم وجود ضمان بأن النص المستخرج سيكون ملائمًا على الشاشة ، فسوف أضع TextView داخل ScrollView.
إليك ملف activity_main.xml النهائي:
يشير هذا التخطيط إلى "ic_placeholder" القابل للدوران ، لذلك دعونا ننشئ هذا الآن:
- حدد "ملف> جديد> Image Asset" من شريط أدوات Android Studio.
- افتح القائمة المنسدلة "نوع الأيقونة" وحدد "شريط الإجراءات وعلامات التبويب".
- تأكد من تحديد زر الاختيار "Clip Art".
- أعط زر "قصاصة فنية" نقرة.
- حدد الصورة التي تريد استخدامها كعنصر نائب ؛ أنا أستخدم "إضافة إلى الصور".
- انقر فوق موافق."
- افتح القائمة المنسدلة "السمة" ، واختر "HOLO_LIGHT".
- في حقل "الاسم" ، أدخل "ic_placeholder".
- انقر فوق "التالي". اقرأ المعلومات ، وإذا كنت سعيدًا بالمتابعة ، فانقر فوق "إنهاء".
رموز شريط الإجراءات: بدء تشغيل تطبيق المعرض
بعد ذلك ، سوف أقوم بإنشاء عنصر شريط إجراءات يبدأ تشغيل معرض المستخدم ، ويكون جاهزًا له لتحديد صورة.
يمكنك تحديد أيقونات شريط الإجراءات داخل ملف مورد قائمة ، والذي يعيش داخل دليل "res / menu". إذا كان مشروعك لا يحتوي على هذا الدليل ، فستحتاج إلى إنشائه:
- انقر مع الضغط على Control على دليل "res" الخاص بمشروعك واختر "New> Android Resource Directory."
- افتح القائمة المنسدلة "نوع المورد" وحدد "القائمة".
- يجب تحديث "اسم الدليل" إلى "القائمة" تلقائيًا ، ولكن إذا لم يكن كذلك ، فستحتاج إلى إعادة تسميته يدويًا.
- انقر فوق موافق."
أنت الآن جاهز لإنشاء ملف مورد القائمة:
- انقر مع الضغط على Control على دليل "قائمة" في مشروعك وحدد "New> ملف مورد القائمة".
- اسم هذا الملف "my_menu".
- انقر فوق موافق."
- افتح ملف "my_menu.xml" ، وأضف ما يلي:
يشير ملف القائمة إلى سلسلة "action_gallery" ، لذا افتح ملف res / values / strings.xml للمشروع الخاص بك وقم بإنشاء هذا المورد. بينما أنا هنا ، أقوم أيضًا بتحديد السلاسل الأخرى التي سنستخدمها في هذا المشروع.
بعد ذلك ، استخدم Image Asset Studio لإنشاء رمز "ic_gallery" بشريط الإجراءات:
- اختر "ملف> جديد> صورة الأصل".
- اضبط القائمة المنسدلة "نوع الأيقونة" على "شريط الإجراءات وعلامات الجدولة".
- انقر فوق الزر "قصاصة فنية".
- اختيار drawable. أنا أستخدم "الصورة".
- انقر فوق موافق."
- للتأكد من أن هذا الرمز مرئي بوضوح في شريط الإجراءات ، افتح القائمة المنسدلة "السمة" وحدد "HOLO_DARK".
- قم بتسمية هذا الرمز "ic_gallery".
- "انقر فوق" التالي "، ثم" إنهاء ".
معالجة طلبات الأذونات والنقر فوق الأحداث
سأقوم بتنفيذ جميع المهام التي لا تتعلق مباشرةً بـ API التعرف على النص في فئة BaseActivity منفصلة ، بما في ذلك إنشاء قائمة من القائمة ، والتعامل مع أحداث النقر فوق شريط الإجراءات ، وطلب الوصول إلى مساحة تخزين الجهاز.
- حدد "ملف> جديد> فئة Java" من شريط أدوات Android Studio.
- اسم هذه الفئة "BaseActivity."
- انقر فوق موافق."
- افتح BaseActivity وأضف ما يلي:
استيراد android.app.Activity ؛ استيراد android.support.v4.app.ActivityCompat؛ استيراد android.support.v7.app.ActionBar؛ استيراد android.support.v7.app.AlertDialog؛ استيراد android.support.v7.app.AppCompatActivity؛ استيراد android.os.Bundle ؛ استيراد android.content.DialogInterface؛ استيراد android.content.Intent ؛ استيراد android.Manifest. استيراد android.provider.MediaStore؛ استيراد android.view.Menu ؛ استيراد android.view.MenuItem؛ استيراد android.content.pm.PackageManager؛ استيراد android.net.Uri ؛ استيراد android.provider.Settings؛ استيراد android.support.annotation.NonNull؛ استيراد android.support.annotation.Nullable؛ استيراد java.io.File ؛ BaseActivity الفئة العامة يمتد AppCompatActivity {public static final int WRITE_STORAGE = 100؛ نهائي ثابت عام int SELECT_PHOTO = 102؛ نهائي ثابت عام StION ACTION_BAR_TITLE = "action_bar_title"؛ ملف الصورة العامة. Override محمية void onCreate (Nullable Bundle saveInstanceState) {super.onCreate (saveInstanceState)؛ ActionBar actionBar = getSupportActionBar ()؛ if (actionBar! = null) {actionBar.setDisplayHomeAsUpEnabled (true)؛ actionBar.setTitle (getIntent () getStringExtra (ACTION_BAR_TITLE))؛ }}Override public boolean onCreateOptionsMenu (Menu Menu) {getMenuInflater (). inflate (R.menu.my_menu، menu)؛ العودة الحقيقية ؛ }Override منطقي عام onOptionsItemSelected (عنصر MenuItem) {switch (item.getItemId ()) {// إذا تم تحديد "gallery_action" ، فعندئذ ... // case R.id.gallery_action: //...check لدينا إذن WRITE_STORAGE // checkPermission (WRITE_STORAGE) ؛ استراحة؛ } إرجاع super.onOptionsItemSelected (item) ؛ }Override public void onRequestPermissionsResult (int requestCode،NonNull String الأذونات،NonNull int grantResults) {super.onRequestPermissionsResult (requestCode، الأذونات، grantResults)؛ التبديل (requestCode) {case WRITE_STORAGE: // إذا تم منح طلب الإذن ، ف ... // if (grantResults.length> 0 && grantResults == PackageManager.PERMISSION_GRANTED) {//...call selectPicture // selectPicture ( )؛ // إذا تم رفض طلب الإذن ، فحينئذٍ ... //} آخر {//.. عرض سلسلة "ذن_الطلب "// requestPermission (هذا ، requestCode ، R.string.permission_request) ؛ } استراحة؛ }} // عرض مربع حوار طلب الإذن // public static void requestPermission (نشاط النشاط النهائي ، requestCode ، int msg) {AlertDialog.Builder alert = new AlertDialog.Builder (نشاط)؛ alert.set (جي اس)؛ alert.setPositiveButton (android.R.string.ok ، DialogInterface.OnClickListener () {Override public void onClick (DialogInterface dialogInterface، int i) {dialogInterface.dismiss ()؛ Intent permissonIntent = new Intent (Settings.ACTION_APPLICATIONSETTAIL_) .setData (Uri.parse ("package:" + activity.getPackageName ()))؛ activity.startActivityForResult (permissonIntent، requestCode)؛}})؛ alert.setNegativeButton (android.R.string.cancel ، DialogInterface.OnClickListener () {Override public void onClick (DialogInterface dialogInterface، int i) {dialogInterface.dismiss ()؛}})؛ alert.setCancelable (كاذبة)؛ alert.show ()؛ } // تحقق مما إذا كان المستخدم قد منح إذن WRITE_STORAGE / / void checkPermission (int requestCode) {switch (requestCode) {case WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (هذا ، Manifest.permission.WRITE_EXTERNAL_STORAGE) ؛ // إذا كان بإمكاننا الوصول إلى وحدة التخزين الخارجية ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//...call selectPicture ، والذي يطلق نشاطًا حيث يمكن للمستخدم تحديد صورة // selectPicture ()؛ // إذا لم يتم منح الإذن ، ف ... //} آخر {//... طلب الإذن // ActivityCompat.requestPermissions (هذا ، سلسلة جديدة {Manifest.permission.WRITE_EXTERNAL_STORAGE} ، requestCode) ؛ } استراحة؛ }} private void selectPicture () {photo = MyHelper.createTempFile (photo)؛ Intent intent = new Intent (Intent.ACTION_PICK، MediaStore.Images.Media.EXTERNAL_CONTENT_URI)؛ // بدء نشاط حيث يمكن للمستخدم اختيار صورة // startActivityForResult (نية ، SELECT_PHOTO) ؛ }}
في هذه المرحلة ، يجب أن يشكو مشروعك من أنه لا يمكن حل MyHelper.createTempFile. لننفذ هذا الآن!
تغيير حجم الصور باستخدام createTempFile
قم بإنشاء فصل "MyHelper" جديد. في هذه الفئة ، سنقوم بتغيير حجم الصورة التي اختارها المستخدم ، جاهزة للتجهيز بواسطة واجهة برمجة تطبيقات التعرف على النص.
استيراد android.graphics.Bitmap ؛ استيراد android.graphics.BitmapFactory ؛ استيراد android.content.Context؛ استيراد android.database.Cursor؛ استيراد android.os.Environment. استيراد android.widget.ImageView ؛ استيراد android.provider.MediaStore؛ استيراد android.net.Uri ؛ استيراد android.graphics ثابت .itmapFactory.decodeFile؛ استيراد ثابت android.graphics.BitmapFactory.decodeStream ؛ استيراد java.io.File ؛ استيراد java.io.FileNotFoundException؛ استيراد java.io.FileOutputStream ؛ استيراد java.io.IOException ؛ الفئة العامة MyHelper {public static getringath Static (سياق السياق ، Uri uri) {String path = ""؛ String projection = {MediaStore.Images.Media.DATA}؛ Cursor cursor = context.getContentResolver (). query (uri، projection، null، null، null)؛ int column_index ؛ if (cursor! = null) {column_index = cursor.getColumnIndexOrThrow (MediaStore.Images.Media.DATA)؛ cursor.moveToFirst ()؛ path = cursor.getString (column_index) ؛ cursor.close ()؛ } مسار العودة؛ } ملف ثابت عام createTempFile (ملف ملف) {File directory = ملف جديد (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication")؛ if (! directory.exists () ||! directory.isDirectory ()) {directory.mkdirs ()؛ } if (file == null) {file = new file (directory، "orig.jpg")؛ ملف الإرجاع } صورة ثابتة ثابتة resizePhoto (ملف imageFile ، سياق السياق ، Uri uri ، ImageView view) {BitmapFactory.Options newOptions = new BitmapFactory.Options ()؛ حاول {decodeStream (context.getContentResolver (). openInputStream (uri) ، null ، newOptions)؛ int photoHeight = newOptions.outHeight؛ int photoWidth = newOptions.outWidth؛ newOptions.inSampleSize = Math.min (photoWidth / view.getWidth () ، photoHeight / view.getHeight ())؛ إرجاع compressPhoto (imageFile ، BitmapFactory.decodeStream (context.getContentResolver (). openInputStream (uri) ، null ، newOptions)) ؛ } catch (استثناء FileNotFoundException) {استثناء.printStackTrace ()؛ عودة لاغية }} صورة ثابتة ثابتة resizePhoto (ملف imageFile ، مسار السلسلة ، عرض ImageView) {BitmapFactory.Options options = new BitmapFactory.Options ()؛ decodeFile (المسار ، الخيارات) ؛ int photoHeight = options.outHeight؛ int photoWidth = options.outWidth؛ options.inSampleSize = Math.min (photoWidth / view.getWidth ()، photoHeight / view.getHeight ())؛ إرجاع compressPhoto (imageFile ، BitmapFactory.decodeFile (المسار ، الخيارات)) ؛ } صورة ثابتة ثابتة للضغط الصوري (File photoFile ، صورة نقطية نقطية) {try {FileOutputStream fOutput = new FileOutputStream (photoFile) ؛ bitmap.compress (Bitmap.CompressFormat.JPEG، 70، fOutput)؛ fOutput.close ()؛ } catch (استثناء IOException) {استثناء.printStackTrace ()؛ } العودة الصورة النقطية؛ }}
اضبط الصورة على ImageView
بعد ذلك ، نحتاج إلى تطبيق onActivityResult () في فئة MainActivity الخاصة بنا ، وتعيين الصورة التي اختارها المستخدم إلى ImageView لدينا.
استيراد android.graphics.Bitmap ؛ استيراد android.os.Bundle ؛ استيراد android.widget.ImageView ؛ استيراد android.content.Intent ؛ استيراد android.widget.TextView؛ استيراد android.net.Uri ؛ توسيع MainActivity من الفئة العامة BaseActivity {private Bitmap myBitmap؛ ImageView الخاص myImageView. TextView myTextView الخاص ؛ Override محمية void onCreate (Bundle saveInstanceState) {super.onCreate (saveInstanceState)؛ setContentView (R.layout.activity_main)؛ myTextView = findViewById (R.id.textView) ؛ myImageView = findViewById (R.id.imageView) ؛ }Override محمية void onActivityResult (int requestCode ، int resultCode ، Intent data) {super.onActivityResult (requestCode ، resultCode ، data)؛ if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode)؛ استراحة؛ الحالة SELECT_PHOTO: Uri dataUri = data.getData ()؛ مسار السلسلة = MyHelper.getPath (هذا ، dataUri) ؛ if (path == null) {myBitmap = MyHelper.resizePhoto (الصورة ، هذا ، dataUri ، myImageView) ؛ } آخر {myBitmap = MyHelper.resizePhoto (الصورة ، المسار ، myImageView) ؛ } if (myBitmap! = null) {myTextView.setText (null)؛ myImageView.setImageBitmap (myBitmap)؛ } استراحة؛ }}}}
قم بتشغيل هذا المشروع على جهاز Android الفعلي أو AVD ، ثم انقر فوق رمز شريط الإجراءات. عند المطالبة ، امنح WRITE_STORAGE إذنًا واختر صورة من المعرض ؛ يجب الآن عرض هذه الصورة في واجهة مستخدم التطبيق.
الآن وضعنا الأساس ، نحن مستعدون للبدء في استخراج بعض النصوص!
تدريس تطبيق للتعرف على النص
أرغب في تشغيل التعرف على النص استجابةً لحدث النقرات ، لذلك نحتاج إلى تطبيق OnClickListener:
استيراد android.graphics.Bitmap ؛ استيراد android.os.Bundle ؛ استيراد android.widget.ImageView ؛ استيراد android.content.Intent ؛ استيراد android.widget.TextView؛ استيراد android.view.View ؛ استيراد android.net.Uri ؛ MainActivity فئة عامة يمتد BaseActivity تنفذ View.OnClickListener {private Bitmap myBitmap؛ ImageView الخاص myImageView. TextView myTextView الخاص ؛ Override محمية void onCreate (Bundle saveInstanceState) {super.onCreate (saveInstanceState)؛ setContentView (R.layout.activity_main)؛ myTextView = findViewById (R.id.textView) ؛ myImageView = findViewById (R.id.imageView) ؛ findViewById (R.id.checkText) .setOnClickListener (هذا)؛ }Override public void onClick (عرض العرض) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = null) {// سنقوم بتنفيذ runTextRecog في الخطوة التالية // runTextRecog ()؛ } استراحة؛ }}
يمكن لمجموعة ML معالجة الصور فقط عندما تكون بتنسيق FirebaseVisionImage ، لذلك نحن بحاجة إلى تحويل صورتنا إلى كائن FirebaseVisionImage. يمكنك إنشاء FirebaseVisionImage من صورة نقطية أو media.Image أو ByteBuffer أو صفيف بايت. نظرًا لأننا نعمل مع الصور النقطية ، نحتاج إلى استدعاء أسلوب الأداة المساعدة fromBitmap () لفئة FirebaseVisionImage ، وتمريرها لدينا.
private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap)؛
يحتوي ML Kit على فئات كشف مختلفة لكل عملية من عمليات التعرف على الصور. بالنسبة للنص ، نحتاج إلى استخدام فئة FirebaseVisionTextDetector ، التي تقوم بالتعرف الضوئي على الأحرف (OCR) على صورة ما.
نقوم بإنشاء مثيل FirebaseVisionTextDetector ، باستخدام getVisionTextDetector:
FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). getVisionTextDetector ()؛
بعد ذلك ، نحتاج إلى التحقق من FirebaseVisionImage للحصول على نص ، عن طريق استدعاء الأسلوب detectInImage () وتمريره كائن FirebaseVisionImage. نحتاج أيضًا إلى تطبيق عمليات الاستعادة onSuccess و onFailure ، بالإضافة إلى المستمعين المقابلين حتى يتم إخطار تطبيقنا عند توفر النتائج.
detector.detectInImage (صورة) .addOnSuccessListener (جديد OnSuccessListener إذا فشلت هذه العملية ، فسأقوم بعرض نخب ، ولكن إذا نجحت العملية ، فسنقوم باستدعاء processExtractedText مع الرد. في هذه المرحلة ، يبدو رمز الكشف عن النص الخاص بي كما يلي: // Create a FirebaseVisionImage // private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap)؛ / / قم بإنشاء نسخة من FirebaseVisionCloudTextDetector // FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). getVisionTextDetector ()؛ / / سجل OnSuccessListener // detector.detectInImage (صورة) .addOnSuccessListener (جديد OnSuccessListener عندما يتلقى تطبيقنا إخطار onSuccess ، نحتاج إلى تحليل النتائج. يمكن أن يحتوي كائن FirebaseVisionText على عناصر وخطوط وكتل ، حيث تساوي كل كتلة عادةً فقرة واحدة من النص. إذا قام FirebaseVisionText بإرجاع 0 كتل ، فسنقوم بعرض سلسلة "no_text" ، ولكن إذا كان يحتوي على واحد أو أكثر من الكتل ، فسنعرض النص المسترجع كجزء من TextView لدينا. عملية باطلة خاصةExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null)؛ if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text)؛ إرجاع؛ } for (FirebaseVisionText.Block block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ())؛ }}} إليك رمز MainActivity المكتمل: استيراد android.graphics.Bitmap ؛ استيراد android.os.Bundle ؛ استيراد android.widget.ImageView ؛ استيراد android.content.Intent ؛ استيراد android.widget.TextView؛ استيراد android.widget.Toast ؛ استيراد android.view.View ؛ استيراد android.net.Uri ؛ استيراد android.support.annotation.NonNull؛ import com.google.firebase.ml.vision.common.FirebaseVisionImage؛ import com.google.firebase.ml.vision.text.FirebaseVisionText؛ import com.google.firebase.ml.vision.text.FirebaseVisionTextDetector؛ import com.google.firebase.ml.vision.FirebaseVision؛ import com.google.android.gms.tasks.OnSuccessListener؛ import com.google.android.gms.tasks.OnFailureListener؛ MainActivity فئة عامة يمتد BaseActivity تنفذ View.OnClickListener {private Bitmap myBitmap؛ ImageView الخاص myImageView. TextView myTextView الخاص ؛ Override محمية void onCreate (Bundle saveInstanceState) {super.onCreate (saveInstanceState)؛ setContentView (R.layout.activity_main)؛ myTextView = findViewById (R.id.textView) ؛ myImageView = findViewById (R.id.imageView) ؛ findViewById (R.id.checkText) .setOnClickListener (هذا)؛ }Override public void onClick (View view) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = null) {runTextRecog ()؛ } استراحة؛ }}Override محمية void onActivityResult (int requestCode ، int resultCode ، Intent data) {super.onActivityResult (requestCode ، resultCode ، data)؛ if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode)؛ استراحة؛ الحالة SELECT_PHOTO: Uri dataUri = data.getData ()؛ مسار السلسلة = MyHelper.getPath (هذا ، dataUri) ؛ if (path == null) {myBitmap = MyHelper.resizePhoto (الصورة ، هذا ، dataUri ، myImageView) ؛ } آخر {myBitmap = MyHelper.resizePhoto (الصورة ، المسار ، myImageView) ؛ } if (myBitmap! = null) {myTextView.setText (null)؛ myImageView.setImageBitmap (myBitmap)؛ } استراحة؛ }}} private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap)؛ FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). getVisionTextDetector ()؛ detector.detectInImage (صورة) .addOnSuccessListener (جديد OnSuccessListener حان الوقت الآن لرؤية تطبيق التعرف على النص في ML Kit! قم بتثبيت هذا المشروع على جهاز Android أو AVD ، واختر صورة من المعرض ، ثم اضغط على زر "التحقق من النص". يجب أن يستجيب التطبيق من خلال استخراج كل النص من الصورة ، ثم عرضها في TextView. لاحظ أنه وفقًا لحجم الصورة ومقدار النص الذي تحتويه ، قد تحتاج إلى التمرير لرؤية النص المستخرج بأكمله. يمكنك أيضًا تنزيل المشروع المكتمل من جيثب. أنت تعرف الآن كيفية اكتشاف واستخراج النص من صورة ، باستخدام ML Kit. واجهة برمجة تطبيقات التعرف على النص ليست سوى جزء واحد من ML Kit. يوفر SDK هذا أيضًا مسح الباركود ، والكشف عن الوجوه ، ووضع علامات على الصور والتعرف على المعالم ، مع وجود خطط لإضافة المزيد من واجهات برمجة التطبيقات لحالات استخدام الأجهزة المحمولة الشائعة ، بما في ذلك الرد الذكي وواجهة برمجة التطبيقات عالية الكثافة للوجه. ما واجهة برمجة تطبيقات ML Kit التي تحبها أكثر شيئ؟ اسمحوا لنا أن نعرف في التعليقات أدناه!اختبار المشروع
تغليف