Cách trích xuất văn bản từ hình ảnh với SDK Google Learning Machine SDK

Tác Giả: John Stephens
Ngày Sáng TạO: 27 Tháng MộT 2021
CậP NhậT Ngày Tháng: 5 Tháng BảY 2024
Anonim
Cách trích xuất văn bản từ hình ảnh với SDK Google Learning Machine SDK - ỨNg DụNg
Cách trích xuất văn bản từ hình ảnh với SDK Google Learning Machine SDK - ỨNg DụNg

NộI Dung


Bạn cũng có thể sử dụng API nhận dạng văn bản làm cơ sở cho các ứng dụng dịch thuật hoặc các dịch vụ trợ năng trong đó người dùng có thể hướng máy ảnh của họ vào bất kỳ văn bản nào mà họ đang đấu tranh và đọc nó cho họ đọc.

Trong hướng dẫn này, chúng tôi sẽ đặt nền tảng cho một loạt các tính năng sáng tạo, bằng cách tạo một ứng dụng có thể trích xuất văn bản từ bất kỳ hình ảnh nào trong thư viện người dùng. Mặc dù chúng tôi đã giành chiến thắng trong phần hướng dẫn này, nhưng bạn cũng có thể chụp văn bản từ môi trường xung quanh người dùng trong thời gian thực bằng cách kết nối ứng dụng này với máy ảnh của thiết bị.

Trên thiết bị hay trên đám mây?

Một số API ML Kit chỉ khả dụng trên thiết bị, nhưng một số API có sẵn trên thiết bị và trên đám mây, bao gồm API nhận dạng văn bản.


API văn bản dựa trên đám mây có thể xác định phạm vi ngôn ngữ và ký tự rộng hơn và hứa hẹn độ chính xác cao hơn so với đối tác trên thiết bị. Tuy nhiên, nó làm yêu cầu kết nối Internet hoạt động và chỉ khả dụng cho các dự án cấp Blaze.

Trong bài viết này, chúng tôi sẽ chạy API nhận dạng văn bản cục bộ, do đó bạn có thể theo dõi bất kể bạn đã nâng cấp lên Blaze hay bạn trong chương trình Firebase Spark miễn phí.

Tạo ứng dụng nhận dạng văn bản với ML Kit

Tạo một ứng dụng với các cài đặt bạn chọn, nhưng khi được nhắc, hãy chọn mẫu Hoạt động trống rỗng.

SDK ML Kit là một phần của Firebase, do đó, bạn sẽ cần kết nối dự án của mình với Firebase, sử dụng chứng chỉ ký SHA-1 của nó. Để nhận dự án của bạn, SHA-1:

  • Chọn tab Android Studio Tải xuống Gradle Gradle.
  • Trong bảng điều khiển các dự án Grad Gradle Bảng điều khiển, nhấp đúp chuột để mở rộng gốc dự án của bạn, ăn, sau đó chọn Nhiệm vụ> Android> Báo cáo ký.
  • Bảng điều khiển dọc phía dưới cửa sổ Android Studio sẽ cập nhật để hiển thị một số thông tin về dự án này - bao gồm chứng chỉ ký SHA-1 của nó.


Để kết nối dự án của bạn với Firebase:

  • Trong trình duyệt web của bạn, khởi chạy Bảng điều khiển Firebase.
  • Chọn dự án Thêm Add.
  • Đặt tên cho dự án của bạn; Tôi sử dụng thử ML ML.
  • Đọc các điều khoản và điều kiện, và nếu bạn vui lòng tiếp tục thì hãy chọn Lôi tôi chấp nhận phạm lỗi, sau đó là dự án Tạo.
  • Chọn Thêm Add Firebase vào ứng dụng Android của bạn.
  • Nhập tên gói dự án của bạn, mà bạn sẽ tìm thấy ở đầu tệp MainActivity và bên trong Bản kê khai.
  • Nhập chứng chỉ ký tên SHA-1 dự án của bạn.
  • Nhấp vào ứng dụng Đăng ký.
  • Chọn Tải xuống Tải xuống google-services.json. Tập tin này chứa tất cả siêu dữ liệu Firebase cần thiết cho dự án của bạn, bao gồm khóa API.
  • Trong Android Studio, kéo và thả tệp google-services.json vào thư mục ứng dụng của bạn.

  • Mở tệp build.gradle cấp dự án của bạn và thêm đường dẫn dịch vụ Google:

classpath com.google.gms: google-services: 4.0.1

  • Mở tệp build.gradle cấp ứng dụng của bạn và thêm các phụ thuộc cho Firebase Core, Firebase ML Vision và trình thông dịch mô hình, cùng với plugin dịch vụ của Google:

áp dụng plugin: com.google.gms.google-services ... ... ... phụ thuộc {tệp thực hiệnTree (dir: libs, bao gồm :) triển khai com.google.firebase: firebase-core: 16.0.1 triển khai com. google.firebase: firebase-ml-Vision: 16.0.0 triển khai com.google.firebase: firebase-ml-model-phiên dịch: 16.0.0

Tại thời điểm này, bạn sẽ cần chạy dự án của mình để có thể kết nối với các máy chủ Firebase:

  • Cài đặt ứng dụng của bạn trên điện thoại thông minh hoặc máy tính bảng Android vật lý hoặc Thiết bị ảo Android (AVD).
  • Trong Bảng điều khiển Firebase, chọn ứng dụng Run Run để xác minh cài đặt.
  • Sau một lúc, bạn sẽ thấy một Chúc mừng Chúc mừng; chọn Tiếp tục vào bảng điều khiển.

Tải xuống các mô hình học máy được đào tạo trước của Google

Theo mặc định, ML Kit chỉ tải xuống các mô hình và khi chúng cần, vì vậy ứng dụng của chúng tôi sẽ tải xuống mô hình OCR khi người dùng cố gắng trích xuất văn bản lần đầu tiên.

Điều này có khả năng có tác động tiêu cực đến trải nghiệm người dùng - hãy tưởng tượng bạn đang cố gắng truy cập một tính năng, chỉ để phát hiện ra rằng ứng dụng phải tải thêm tài nguyên trước khi nó thực sự có thể cung cấp tính năng này. Trong trường hợp xấu nhất, ứng dụng của bạn thậm chí không thể tải xuống các tài nguyên mà nó cần, khi cần, ví dụ nếu thiết bị không có kết nối Internet.

Để chắc chắn rằng điều này không xảy ra với ứng dụng của chúng tôi, tôi sẽ tải xuống mô hình OCR cần thiết vào thời gian cài đặt, yêu cầu một số thay đổi đối với Maniest.

Trong khi chúng tôi mở Manifest, tôi cũng sẽ thêm quyền WRITE_EXTERNAL_STORAGE, mà chúng tôi sẽ sử dụng nó sau này trong hướng dẫn này.

// Thêm quyền WRITE_EXTERNAL_STORAGE // //Thêm những điều sau//

Xây dựng bố cục

Hãy để Vượt qua những thứ dễ dàng và tạo ra một bố cục bao gồm:

  • Một ImageView. Ban đầu, điều này sẽ hiển thị một trình giữ chỗ, nhưng nó sẽ cập nhật một khi người dùng chọn một hình ảnh từ bộ sưu tập của họ.
  • Nút, kích hoạt trích xuất văn bản.
  • Một TextView, trong đó chúng tôi sẽ hiển thị văn bản được trích xuất.
  • Một ScrollView. Vì không có gì đảm bảo văn bản trích xuất sẽ nằm gọn trên màn hình, nên tôi sẽ đặt TextView bên trong ScrollView.

Tại đây, tập tin đã hoàn thành tệp Activity_main.xml:

Bố cục này tham khảo một bản vẽ có thể rút ra của ic ic

  • Chọn Tệp tin >> Mới> Tài sản hình ảnh từ thanh công cụ Android Studio.
  • Mở trình đơn thả xuống Loại biểu tượng và chọn biểu tượng hành động và biểu tượng.
  • Hãy chắc chắn rằng nút radio của Clip Clip Nghệ thuật được chọn.
  • Hãy nhấn nút Clip Clip Nghệ thuật.
  • Chọn hình ảnh bạn muốn sử dụng làm trình giữ chỗ của bạn; Tôi sử dụng Thêm vào hình ảnh.
  • Nhấp vào OK OK.
  • Mở danh sách thả xuống của Theme Theme và chọn vào HOL HOL_L_L.
  • Trong trường Tên, tên miền, hãy nhập vào ic_placeholder.
  • Nhấp vào Tiếp theo. Tiếp tục đọc thông tin và nếu bạn vui lòng tiếp tục thì hãy nhấp vào Kết thúc.

Biểu tượng trên thanh hành động: Khởi chạy ứng dụng Thư viện

Tiếp theo, tôi sẽ tạo một mục trên thanh hành động để ra mắt bộ sưu tập người dùng, sẵn sàng cho họ chọn một hình ảnh.

Bạn xác định các biểu tượng thanh hành động bên trong một tệp tài nguyên menu, nằm trong thư mục của Res res / menu. Nếu dự án của bạn không có chứa thư mục này, thì bạn sẽ cần phải tạo nó:

  • Nhấp chuột vào thư mục dự án của bạn
  • Mở trình đơn thả xuống của loại Tài nguyên và chọn menu.
  • Tên thư mục của NỮA nên tự động cập nhật lên menu Menu, nhưng nếu không có thì bạn sẽ phải đổi tên thủ công.
  • Nhấp vào OK OK.

Bây giờ bạn đã sẵn sàng để tạo tệp tài nguyên menu:

  • Nhấp chuột phải vào dự án của bạn
  • Đặt tên cho tập tin này là my mymen.
  • Nhấp vào OK OK.
  • Mở tệp tin my_menu.xml, và thêm vào đây:

//Tạo ra một phần tử cho mọi hành động //

Tệp trình đơn tham chiếu một chuỗi action_gallery, một chuỗi hành động, vì vậy hãy mở tệp dự án của bạn res / giá trị / chuỗi tệp và tạo tài nguyên này. Trong khi tôi ở đây, tôi cũng xác định các chuỗi khác mà chúng tôi sẽ sử dụng trong suốt dự án này.

Bộ sưu tập Ứng dụng này cần truy cập các tập tin trên thiết bị của bạn. Không tìm thấy văn bản

Tiếp theo, sử dụng Studio Asset Studio để tạo thanh hành động biểu tượng ic Thời trang ic_gallery:

  • Chọn tập tin của New York> Mới> Tài sản hình ảnh.
  • Đặt biểu tượng thả xuống Loại biểu tượng của người hâm mộ thành biểu tượng hành động và biểu tượng tab.
  • Nhấp vào nút Clip Clip Nghệ thuật.
  • Chọn một drawable; Tôi sử dụng hình ảnh trên mạng.
  • Nhấp vào OK OK.
  • Để đảm bảo biểu tượng này hiển thị rõ ràng trong thanh hành động, hãy mở trình đơn thả xuống của Theme Theme và chọn CÂU HOLO_DARK.
  • Đặt tên cho biểu tượng này là ic ic_gallery.
  • Tiếp theo

Xử lý các yêu cầu cấp phép và nhấp vào các sự kiện

Tôi sẽ thực hiện tất cả các tác vụ liên quan trực tiếp đến API nhận dạng văn bản trong một lớp BaseActivity riêng biệt, bao gồm khởi tạo menu, xử lý các sự kiện nhấp vào thanh hành động và yêu cầu quyền truy cập vào bộ lưu trữ của thiết bị.

  • Chọn Tệp Tệp> Mới> Lớp Java Java từ thanh công cụ Android Studio.
  • Đặt tên cho lớp này là Base BaseActivity.
  • Nhấp vào OK OK.
  • Mở BaseActivity và thêm vào như sau:

nhập android.app.Activity; nhập android.support.v4.app.ActivityCompat; nhập android.support.v7.app.ActionBar; nhập android.support.v7.app.AlertDialog; nhập android.support.v7.app.AppCompatActivity; nhập android.os.Bundle; nhập android.content.DialogInterface; nhập android.content.Intent; nhập android.Manifest; nhập android.provider.MediaStore; nhập android.view.Mothy; nhập android.view.MothyItem; nhập android.content.pm.PackageManager; nhập android.net.Uri; nhập android.provider.S Settings; nhập android.support.annotation.NonNull; nhập android.support.annotation.Nullable; nhập java.io.File; lớp công khai BaseActivity mở rộng AppCompatActivity {chung tĩnh int int WRITE_STORAGE = 100; chung tĩnh tĩnh int SELECT_PHOTO = 102; Chuỗi cuối cùng tĩnh công khai ACTION_BAR_TITLE = "action_bar_title"; Ảnh công khai; @Override được bảo vệ void onCreate (@Nullable Gói đã lưuInstanceState) {super.onCreate (yetInstanceState); ActionBar actionBar = getSupportActionBar (); if (actionBar! = null) {actionBar.setDisplayHomeAsUpEnables (true); actionBar.setTitle (getIntent (). getStringExtra (ACTION_BAR_TITLE)); }} @Override boolean công khai onCreateOptionsMothy (Menu menu) {getMothyInflater (). Inflate (R.menu.my_menu, menu); trả lại đúng sự thật; } @Override boolean công khai onOptionsItemSelected (mục MenuItem) {switch (item.getItemId ()) {// Nếu thư viện Gallery_action, được chọn, thì ... // case R.id.gallery_action: //...check chúng tôi có quyền WRITE_STORAGE // checkPermission (WRITE_STORAGE); phá vỡ; } return super.onOptionsItemSelected (item); } @Override void công khai onRequestPermissionsResult (int requestCode, @NonNull Chuỗi quyền, @NonNull int GrantResults) {super.onRequestPermissionsResult (requestCode, allow, GrantResults); switch (requestCode) {case WRITE_STORAGE: // Nếu yêu cầu cấp phép được cấp, thì ... // if (GrantResults.length> 0 && GrantResults == PackageManager.PERMISSION_GRANTED) {//..call selectPicture // selectPicture ); // Nếu yêu cầu cấp phép bị từ chối, thì ... //} khác {//...display chuỗi quyền allow_Vquest Dòng // requestPermission (this, requestCode, R.opes-bitquququest); } phá vỡ; }} // Hiển thị hộp thoại yêu cầu cấp phép // public static void requestPermission (Hoạt động cuối cùng, int int requestCode, int messenger) {AlertDialog.Builder alert = new AlertDialog.Builder (hoạt động); alert.set (tin nhắn); alert.setPositiveButton (android.R.opes.ok, DialogInterface.OnClickListener () {@Override công khai void onClick (Hộp thoại DialogInterfaceInterface, int i) {hộp thoại .setData (Uri.parse ("gói:" + Activity.getPackageName ())); Activity.startActivityForResult (permissonIntent, requestCode);}}); alert.setNegativeButton (android.R.opes.celon, DialogInterface.OnClickListener () {@Override công khai void onClick (DialogInterface đàm thoạiInterface, int i) {hộpInterface.dismiss ();}}); alert.set Hủy được (sai); cảnh báo.show (); } // Kiểm tra xem người dùng đã cấp quyền WRITE_STORAGE // công khai void checkPermission (int requestCode) {switch (requestCode) {case WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (this, Manifest. // Nếu chúng ta có quyền truy cập vào bộ nhớ ngoài ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//..call selectPicture, sẽ khởi chạy một Activity mà người dùng có thể chọn một hình ảnh // selectPicture (); // Nếu quyền đã được cấp, thì ... //} khác {//... không yêu cầu quyền // ActivityCompat.requestPermissions (này, Chuỗi mới {Manifestÿ.WRITE_EXTERNAL_STORAGE}, requestCode); } phá vỡ; }} void void selectPicture () {photo = MyHelper.createTempFile (ảnh); Mục đích ý định = Ý định mới (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // Bắt đầu một Hoạt động trong đó người dùng có thể chọn một hình ảnh // startActivityForResult (ý định, SELECT_PHOTO); }}

Tại thời điểm này, dự án của bạn nên phàn nàn rằng nó có thể giải quyết MyHelper.createTempFile. Hãy để thực hiện điều này bây giờ!

Thay đổi kích thước hình ảnh với createdTempFile

Tạo một lớp MyHelper mới. Trong lớp này, chúng tôi sẽ thay đổi kích thước hình ảnh người dùng đã chọn, sẵn sàng để được xử lý bởi API nhận dạng văn bản.

nhập android.graphics.Bitmap; nhập android.graphics.BitmapFactory; nhập android.content.Context; nhập android.database.Coder; nhập android.os.EnFE; nhập android.widget.ImageView; nhập android.provider.MediaStore; nhập android.net.Uri; nhập android.graphics.BitmapFactory.decodeFile tĩnh; nhập android.graphics.BitmapFactory.decodeStream tĩnh; nhập java.io.File; nhập java.io.FileNotFoundException; nhập java.io.FileOutputStream; nhập java.io.IOException; lớp công khai MyHelper {chuỗi tĩnh công khai getPath (Ngữ cảnh ngữ cảnh, Uri uri) {String path = ""; Trình chiếu chuỗi = {MediaStore.Images.Media.DATA}; Con trỏ con trỏ = bối cảnh.getContentResolver (). Truy vấn (uri, chiếu, null, null, null); int cột_index; if (con trỏ! = null) {cột_index = con trỏ.getColumnIndexOrThrow (MediaStore.Images.Media.DATA); con trỏ.moveToFirst (); path = con trỏ.getString (cột_index); con trỏ.close (); } đường dẫn trở lại; } Tệp tĩnh công khai createdTempFile (Tệp tệp) {Tệp thư mục = Tệp mới (Môi trường.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication"); if (! thư mục.exists () ||! thư mục.isDirectory ()) {thư mục.mkdirs (); } if (file == null) {file = new File (thư mục, "orig.jpg"); } trả lại tập tin; } Thay đổi kích thước Bitmap tĩnh tĩnh (Ảnh imageFile, Ngữ cảnh ngữ cảnh, Uri uri, Chế độ xem ImageView) {BitmapFactory.Options newOptions = new BitmapFactory.Options (); thử {decodeStream (bối cảnh.getContentResolver (). openInputStream (uri), null, newOptions); int photoHeight = newOptions.outHeight; int photoWidth = newOptions.outWidth; newOptions.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); return nénPhoto (imageFile, BitmapFactory.decodeStream (bối cảnh.getContentResolver (). openInputStream (uri), null, newOptions)); } Catch (ngoại lệ FileNotFoundException) {ngoại lệ.printStackTrace (); trả về null; }} Thay đổi kích thước Bitmap tĩnh tĩnh công khai (Tệp imageFile, Đường dẫn chuỗi, Chế độ xem ImageView) {BitmapFactory.Options tùy chọn = new BitmapFactory.Options (); decodeFile (đường dẫn, tùy chọn); int photoHeight = Options.outHeight; int photoWidth = tùy chọn.outWidth; tùy chọn.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); trả về nénPhoto (imageFile, BitmapFactory.decodeFile (đường dẫn, tùy chọn)); } nén bitmap tĩnh riêng tưPhoto (File photoFile, Bitmap bitmap) {thử {FileOutputStream fOutput = new FileOutputStream (photoFile); bitmap.compress (Bitmap.CompressFormat.JPEG, 70, fOutput); fOutput.c Đóng (); } Catch (ngoại lệ IOException) {ngoại lệ.printStackTrace (); } bitmap trả về; }}

Đặt hình ảnh thành ImageView

Tiếp theo, chúng ta cần triển khai onActivityResult () trong lớp MainActivity của mình và đặt hình ảnh người dùng đã chọn vào ImageView của chúng tôi.

nhập android.graphics.Bitmap; nhập android.os.Bundle; nhập android.widget.ImageView; nhập android.content.Intent; nhập android.widget.TextView; nhập android.net.Uri; lớp công khai MainActivity mở rộng BaseActivity {private Bitmap myBitmap; hình ảnh riêng tư myImageView; TextView myTextView riêng tư; @Override void void onCreate (Gói đã lưuInstanceState) {super.onCreate (yetInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); } @Override void void onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); phá vỡ; trường hợp SELECT_PHOTO: Uri dataUri = data.getData (); Chuỗi đường dẫn = MyHelper.getPath (this, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (ảnh, này, dataUri, myImageView); } other {myBitmap = MyHelper.resizePhoto (ảnh, đường dẫn, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } phá vỡ; }}}}

Chạy dự án này trên thiết bị Android vật lý hoặc AVD và nhấp vào biểu tượng thanh hành động. Khi được nhắc, hãy cấp quyền WRITE_STORAGE và chọn một hình ảnh từ thư viện; hình ảnh này sẽ được hiển thị trong UI UI ứng dụng của bạn.

Bây giờ chúng tôi đã đặt nền móng, chúng tôi đã sẵn sàng để bắt đầu trích xuất một số văn bản!

Dạy một ứng dụng để nhận dạng văn bản

Tôi muốn kích hoạt nhận dạng văn bản để đáp ứng với sự kiện nhấp chuột, vì vậy chúng tôi cần triển khai OnClickListener:

nhập android.graphics.Bitmap; nhập android.os.Bundle; nhập android.widget.ImageView; nhập android.content.Intent; nhập android.widget.TextView; nhập android.view.View; nhập android.net.Uri; lớp công khai MainActivity mở rộng BaseActivity thực hiện View.OnClickListener {private Bitmap myBitmap; hình ảnh riêng tư myImageView; TextView myTextView riêng tư; @Override void void onCreate (Gói đã lưuInstanceState) {super.onCreate (yetInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (cái này); } @Override void công khai onClick (Xem chế độ xem) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {// Chúng tôi sẽ triển khai runTextRecog trong bước tiếp theo // runTextRecog (); } phá vỡ; }}

ML Kit chỉ có thể xử lý hình ảnh khi chúng ở chế độ FirebaseVisionImage, vì vậy chúng ta cần chuyển đổi hình ảnh của mình thành đối tượng FirebaseVisionImage. Bạn có thể tạo FirebaseVisionImage từ Bitmap, media.Image, ByteBuffer hoặc một mảng byte. Vì chúng tôi đang làm việc với Bitmap, chúng tôi cần gọi phương thức tiện ích fromBitmap () của lớp FirebaseVisionImage và truyền cho Bitmap của chúng tôi.

private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap);

ML Kit có các lớp dò khác nhau cho mỗi hoạt động nhận dạng hình ảnh của nó. Đối với văn bản, chúng ta cần sử dụng lớp FirebaseVisionTextDetector, thực hiện nhận dạng ký tự quang học (OCR) trên một hình ảnh.

Chúng tôi tạo một phiên bản của FirebaseVisionTextDetector, sử dụng getVisionTextDetector:

Trình phát hiện FirebaseVisionTextDetector = FirebaseVision.getInstance (). GetVisionTextDetector ();

Tiếp theo, chúng ta cần kiểm tra văn bản FirebaseVisionImage, bằng cách gọi phương thức DetInImage () và truyền cho nó đối tượng FirebaseVisionImage. Chúng tôi cũng cần triển khai các cuộc gọi lại onSuccess và onFailure, cộng với người nghe tương ứng để ứng dụng của chúng tôi được thông báo mỗi khi có kết quả.

dò.detectInImage (hình ảnh) .addOnSuccessListener (OnSuccessListener mới() {@Override // Để làm //}}). AddOnFailureListener (new OnFailureListener () {@Override void công khai onFailure (ngoại lệ @NonNull Exception) {// Nhiệm vụ không thành công với ngoại lệ //}}); }

Nếu thao tác này thất bại, thì tôi sẽ hiển thị một cái bánh mì nướng, nhưng nếu hoạt động thành công thì tôi sẽ gọi processExtractedText với phản hồi.

Tại thời điểm này, mã phát hiện văn bản của tôi trông như thế này:

// Tạo một FirebaseVisionImage // private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); // Tạo một phiên bản của FirebaseVisionCloudTextDetector // Trình phát hiện FirebaseVisionTextDetector = FirebaseVision.getInstance (). GetVisionTextDetector (); // Đăng ký một OnSuccessListener // dò.detectInImage (hình ảnh) .addOnSuccessListener (OnSuccessListener mới() {@Override // Thực hiện cuộc gọi lại onSuccess // public void onSuccess (văn bản FirebaseVisionText) {// Gọi processExtractedText với phản hồi // processExtractedText (text); }}). addOnFailureListener (new OnFailureListener () {@Override // Thực hiện calback onFailure // public void onFailure (ngoại lệ @NonNull Exception) {Toast.makeText (MainActivity.this, "Exception", "Ngoại lệ" );}}); }

Bất cứ khi nào ứng dụng của chúng tôi nhận được thông báo onSuccess, chúng tôi cần phân tích kết quả.

Một đối tượng FirebaseVisionText có thể chứa các thành phần, dòng và khối, trong đó mỗi khối thường tương đương với một đoạn văn bản. Nếu FirebaseVisionText trả về 0 khối, thì chúng tôi sẽ hiển thị chuỗi không có văn bản, nhưng nếu nó chứa một hoặc nhiều khối thì chúng tôi sẽ hiển thị văn bản được truy xuất như một phần của TextView.

private void processExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.opes.no tựa); trở về; } cho (Khối FirebaseVisionText.Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Tại đây, mã MainActivity đã hoàn thành:

nhập android.graphics.Bitmap; nhập android.os.Bundle; nhập android.widget.ImageView; nhập android.content.Intent; nhập android.widget.TextView; nhập android.widget.Toast; nhập android.view.View; nhập android.net.Uri; nhập android.support.annotation.NonNull; nhập com.google.firebase.ml.vision.common.FirebaseVisionImage; nhập com.google.firebase.ml.vision.text.FirebaseVisionText; nhập com.google.firebase.ml.vision.text.FirebaseVisionTextDetector; nhập com.google.firebase.ml.vision.FirebaseVision; nhập com.google.android.gms.t task.OnSuccessListener; nhập com.google.android.gms.t task.OnFailureListener; lớp công khai MainActivity mở rộng BaseActivity thực hiện View.OnClickListener {private Bitmap myBitmap; hình ảnh riêng tư myImageView; TextView myTextView riêng tư; @Override void void onCreate (Gói đã lưuInstanceState) {super.onCreate (yetInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (cái này); } @Override void công khai onClick (Xem chế độ xem) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {runTextRecog (); } phá vỡ; }} @Override void void onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); phá vỡ; trường hợp SELECT_PHOTO: Uri dataUri = data.getData (); Chuỗi đường dẫn = MyHelper.getPath (this, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (ảnh, này, dataUri, myImageView); } other {myBitmap = MyHelper.resizePhoto (ảnh, đường dẫn, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } phá vỡ; }}} private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); Trình phát hiện FirebaseVisionTextDetector = FirebaseVision.getInstance (). GetVisionTextDetector (); dò.detectInImage (hình ảnh) .addOnSuccessListener (OnSuccessListener mới() {@Override void công khai onSuccess (văn bản FirebaseVisionText) {processExtractedText (văn bản); }}). addOnFailureListener (new OnFailureListener () {@Override void công khai onFailure (@NonNull Ngoại lệ ngoại lệ) {Toast.makeText (MainActivity.this, "Exception", Toast.LENGTH_LONG) .show } process void privateExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.opes.no tựa); trở về; } cho (Khối FirebaseVisionText.Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Kiểm tra dự án

Bây giờ đã đến lúc để thấy ML Kit từ nhận dạng văn bản hoạt động! Cài đặt dự án này trên thiết bị Android hoặc AVD, chọn một hình ảnh từ thư viện và sau đó nhấn nút Kiểm tra văn bản. Ứng dụng sẽ phản hồi bằng cách trích xuất tất cả văn bản từ hình ảnh, sau đó hiển thị nó trong TextView.

Lưu ý rằng tùy thuộc vào kích thước hình ảnh của bạn và số lượng văn bản chứa trong đó, bạn có thể cần phải cuộn để xem tất cả văn bản được trích xuất.

Bạn cũng có thể tải xuống dự án đã hoàn thành từ GitHub.

Gói lại

Bây giờ bạn đã biết cách phát hiện và trích xuất văn bản từ một hình ảnh, sử dụng ML Kit.

API nhận dạng văn bản chỉ là một phần của ML Kit. SDK này cũng cung cấp chức năng quét mã vạch, nhận diện khuôn mặt, ghi nhãn hình ảnh và nhận dạng mốc, với kế hoạch thêm nhiều API cho các trường hợp sử dụng di động phổ biến, bao gồm Trả lời thông minh và API đường viền mặt mật độ cao.

API ML Kit nào mà bạn quan tâm nhất để thử? Cho chúng tôi biết trong các ý kiến ​​dưới đây!

Ưu đãi ahoy! Chúng tôi đã bắt được gió của một giảm giá lớn Google Expre trên một ố ản phẩm chơi game hàng đầu, bao gồm một ố gói Xbox One X. Nó chỉ c...

Mặc dù Google Expre đã xuất hiện khá lâu nhưng bạn có thể chưa bao giờ ử dụng nó trước đây. Google Expre là Google cố gắng tiếp nhận Amazon với các lô...

Thú Vị