Cómo extraer texto de imágenes con el SDK de aprendizaje automático de Google

Autor: John Stephens
Fecha De Creación: 27 Enero 2021
Fecha De Actualización: 5 Mes De Julio 2024
Anonim
Cómo extraer texto de imágenes con el SDK de aprendizaje automático de Google - Aplicaciones
Cómo extraer texto de imágenes con el SDK de aprendizaje automático de Google - Aplicaciones

Contenido


También puede usar la API de reconocimiento de texto como base para aplicaciones de traducción o servicios de accesibilidad donde el usuario puede apuntar con su cámara a cualquier texto con el que esté luchando y que se lo lea en voz alta.

En este tutorial, sentaremos las bases para una amplia gama de características innovadoras, al crear una aplicación que pueda extraer texto de cualquier imagen en la galería del usuario. Aunque no lo cubriremos en este tutorial, también puede capturar texto del entorno del usuario en tiempo real, conectando esta aplicación a la cámara del dispositivo.

¿En el dispositivo o en la nube?

Algunas de las API de ML Kit solo están disponibles en el dispositivo, pero algunas están disponibles en el dispositivo y en la nube, incluida la API de reconocimiento de texto.

La API de texto basada en la nube puede identificar una gama más amplia de idiomas y caracteres, y promete una mayor precisión que su contraparte en el dispositivo. De todos modos, eso hace requieren una conexión a Internet activa y solo está disponible para proyectos de nivel Blaze.


En este artículo, ejecutaremos la API de reconocimiento de texto localmente, para que pueda seguir independientemente de si ha actualizado a Blaze o si está en el plan gratuito de Firebase Spark.

Crear una aplicación de reconocimiento de texto con ML Kit

Cree una aplicación con la configuración que elija, pero cuando se le solicite, seleccione la plantilla "Actividad vacía".

ML Kit SDK es parte de Firebase, por lo que deberá conectar su proyecto a Firebase, utilizando su certificado de firma SHA-1. Para obtener el SHA-1 de su proyecto:

  • Seleccione la pestaña "Gradle" de Android Studio.
  • En el panel "Proyectos de Gradle", haga doble clic para expandir la "raíz" de su proyecto y luego seleccione "Tareas> Android> Informe de firma".
  • El panel en la parte inferior de la ventana de Android Studio debería actualizarse para mostrar información sobre este proyecto, incluido su certificado de firma SHA-1.


Para conectar su proyecto a Firebase:

  • En su navegador web, inicie Firebase Console.
  • Seleccione "Agregar proyecto".
  • Dale un nombre a tu proyecto; Estoy usando la "Prueba ML".
  • Lea los términos y condiciones, y si está contento de continuar, seleccione "Acepto ..." seguido de "Crear proyecto".
  • Seleccione "Agregar Firebase a su aplicación de Android".
  • Ingrese el nombre del paquete de su proyecto, que encontrará en la parte superior del archivo MainActivity y dentro del Manifiesto.
  • Ingrese el certificado de firma SHA-1 de su proyecto.
  • Haga clic en "Registrar aplicación".
  • Seleccione "Descargar google-services.json". Este archivo contiene todos los metadatos de Firebase necesarios para su proyecto, incluida la clave API.
  • En Android Studio, arrastre y suelte el archivo google-services.json en el directorio "aplicación" de su proyecto.

  • Abra su archivo build.gradle a nivel de proyecto y agregue la ruta de clase de servicios de Google:

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

  • Abra su archivo build.gradle de nivel de aplicación y agregue dependencias para Firebase Core, Firebase ML Vision y el intérprete de modelos, además del complemento de servicios de Google:

aplique el complemento: com.google.gms.google-services ... ... ... dependencias {implementación fileTree (dir: libs, include:) implementación com.google.firebase: firebase-core: 16.0.1 implementación com. google.firebase: firebase-ml-vision: 16.0.0 implementación com.google.firebase: firebase-ml-model-interpreter: 16.0.0

En este punto, deberá ejecutar su proyecto para que pueda conectarse a los servidores de Firebase:

  • Instale su aplicación en un teléfono inteligente o tableta Android física, o en un dispositivo virtual Android (AVD).
  • En Firebase Console, seleccione "Ejecutar aplicación para verificar la instalación".
  • Después de unos momentos, debería ver un "Felicitaciones"; seleccione "Continuar a la consola".

Descargue los modelos de aprendizaje automático preformados de Google

De manera predeterminada, ML Kit solo descarga modelos cuando sea necesario, por lo que nuestra aplicación descargará el modelo OCR cuando el usuario intente extraer texto por primera vez.

Esto podría tener un impacto negativo en la experiencia del usuario: imagine intentar acceder a una función, solo para descubrir que la aplicación tiene que descargar más recursos antes de que realmente pueda ofrecer esta función. En el peor de los casos, es posible que su aplicación ni siquiera pueda descargar los recursos que necesita, cuando los necesita, por ejemplo, si el dispositivo no tiene conexión a Internet.

Para asegurarme de que esto no suceda con nuestra aplicación, voy a descargar el modelo de OCR necesario en el momento de la instalación, que requiere algunos cambios en Maniest.

Si bien tenemos abierto el Manifiesto, también voy a agregar el permiso WRITE_EXTERNAL_STORAGE, que lo utilizaremos más adelante en este tutorial.

// Agregue el permiso WRITE_EXTERNAL_STORAGE // // Agrega lo siguiente //

Construyendo el diseño

Vamos a sacar las cosas fáciles del camino y crear un diseño que consista en:

  • Un ImageView. Inicialmente, esto mostrará un marcador de posición, pero se actualizará una vez que el usuario seleccione una imagen de su galería.
  • Un botón, que activa la extracción de texto.
  • Una vista de texto, donde mostraremos el texto extraído.
  • Una vista de desplazamiento. Como no hay garantía de que el texto extraído se ajuste perfectamente en la pantalla, voy a colocar TextView dentro de ScrollView.

Aquí está el archivo de activity_main.xml terminado:

Este diseño hace referencia a un dibujo "ic_placeholder", así que creemos esto ahora:

  • Seleccione "Archivo> Nuevo> Activo de imagen" en la barra de herramientas de Android Studio.
  • Abra el menú desplegable "Tipo de icono" y seleccione "Barra de acción e iconos de pestaña".
  • Asegúrese de que esté seleccionado el botón de opción "Imágenes prediseñadas".
  • Haga clic en el botón "Clip Art".
  • Seleccione la imagen que desea usar como marcador de posición; Estoy usando "Agregar a fotos".
  • Haga clic en Aceptar."
  • Abra el menú desplegable "Tema" y seleccione "HOLO_LIGHT".
  • En el campo "Nombre", ingrese "ic_placeholder".
  • Haga clic en "Siguiente". Lea la información y, si está contento de continuar, haga clic en "Finalizar".

Iconos de la barra de acción: iniciar la aplicación Galería

A continuación, voy a crear un elemento de barra de acción que abrirá la galería del usuario, listo para que seleccione una imagen.

Defina los iconos de la barra de acción dentro de un archivo de recursos de menú, que se encuentra dentro del directorio "res / menu". Si su proyecto no contiene este directorio, deberá crearlo:

  • Mantenga presionada la tecla Control y haga clic en el directorio "res" de su proyecto y seleccione "Nuevo> Directorio de recursos de Android".
  • Abra el menú desplegable "Tipo de recurso" y seleccione "menú".
  • El "Nombre del directorio" debería actualizarse al "menú" automáticamente, pero si no es así, deberá cambiarle el nombre manualmente.
  • Haga clic en Aceptar."

Ahora está listo para crear el archivo de recursos del menú:

  • Mantenga presionada la tecla Control y haga clic en el directorio "menú" de su proyecto y seleccione "Nuevo> Archivo de recursos del menú".
  • Nombre este archivo "my_menu".
  • Haga clic en Aceptar."
  • Abra el archivo "my_menu.xml" y agregue lo siguiente:

//Crear un elemento para cada acción //

El archivo de menú hace referencia a una cadena "action_gallery", por lo tanto, abra el archivo res / values ​​/ strings.xml de su proyecto y cree este recurso. Mientras estoy aquí, también estoy definiendo las otras cadenas que usaremos a lo largo de este proyecto.

Galería Esta aplicación necesita acceder a los archivos en su dispositivo. No se encontró texto.

A continuación, use Image Asset Studio para crear el icono "ic_gallery" de la barra de acción:

  • Seleccione "Archivo> Nuevo> Activo de imagen".
  • Establezca el menú desplegable "Tipo de icono" en "Barra de acción e iconos de pestaña".
  • Haga clic en el botón "Clip Art".
  • Elige un dibujable; Estoy usando "imagen".
  • Haga clic en Aceptar."
  • Para asegurarse de que este icono esté claramente visible en la barra de acción, abra el menú desplegable "Tema" y seleccione "HOLO_DARK".
  • Nombre este icono "ic_gallery".
  • "Haga clic en" Siguiente ", seguido de" Finalizar ".

Manejo de solicitudes de permisos y eventos de clic

Voy a realizar todas las tareas que no están directamente relacionadas con la API de reconocimiento de texto en una clase BaseActivity separada, incluida la creación de instancias del menú, el manejo de eventos de clic de la barra de acción y la solicitud de acceso al almacenamiento del dispositivo.

  • Seleccione "Archivo> Nuevo> clase Java" en la barra de herramientas de Android Studio.
  • Nombre esta clase "BaseActivity".
  • Haga clic en Aceptar."
  • Abra BaseActivity y agregue lo siguiente:

importar android.app.Activity; importar android.support.v4.app.ActivityCompat; importar android.support.v7.app.ActionBar; importar android.support.v7.app.AlertDialog; importar android.support.v7.app.AppCompatActivity; importar android.os.Bundle; importar android.content.DialogInterface; importar android.content.Intent; importar android.Manifest; importar android.provider.MediaStore; importar android.view.Menu; importar android.view.MenuItem; importar android.content.pm.PackageManager; importar android.net.Uri; importar android.provider.Settings; importar android.support.annotation.NonNull; importar android.support.annotation.Nullable; import java.io.File; BaseActivity de clase pública extiende AppCompatActivity {public static final int WRITE_STORAGE = 100; public static final int SELECT_PHOTO = 102; public static final Cadena ACTION_BAR_TITLE = "action_bar_title"; Foto de archivo pública; @Override protected void onCreate (@Nullable Bundle savedInstanceState) {super.onCreate (savedInstanceState); ActionBar actionBar = getSupportActionBar (); if (actionBar! = null) {actionBar.setDisplayHomeAsUpEnabled (verdadero); actionBar.setTitle (getIntent (). getStringExtra (ACTION_BAR_TITLE)); }} @Override public boolean onCreateOptionsMenu (Menú de menú) {getMenuInflater (). Inflate (R.menu.my_menu, menú); volver verdadero; } @Override public boolean onOptionsItemSelected (elemento MenuItem) {switch (item.getItemId ()) {// Si se selecciona "gallery_action", entonces ... // case R.id.gallery_action: //...check tenemos el permiso WRITE_STORAGE // checkPermission (WRITE_STORAGE); descanso; } return super.onOptionsItemSelected (item); } @Override public void onRequestPermissionsResult (int requestCode, @NonNull String permissions, @NonNull int grantResults) {super.onRequestPermissionsResult (requestCode, permissions, grantResults); switch (requestCode) {case WRITE_STORAGE: // Si se otorga la solicitud de permiso, entonces ... // if (grantResults.length> 0 && grantResults == PackageManager.PERMISSION_GRANTED) {//...call selectPicture // selectPicture ( ); // Si la solicitud de permiso es denegada, entonces ... //} else {//...muestra la cadena "permission_request" // requestPermission (this, requestCode, R.string.permission_request); } rotura; }} // Mostrar el cuadro de diálogo de solicitud de permiso // public static void requestPermission (actividad de actividad final, int int requestCode, int msg) {AlertDialog.Builder alert = new AlertDialog.Builder (activity); alert.set (msg); alert.setPositiveButton (android.R.string.ok, new DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss (); Intent permissonIntent = new Intent (Settings.ACTION_APPLICATION_DETA; .setData (Uri.parse ("paquete:" + activity.getPackageName ())); activity.startActivityForResult (permissonIntent, requestCode);}}); alert.setNegativeButton (android.R.string.cancel, new DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss ();}}); alert.setCancelable (falso); alert.show (); } // Compruebe si el usuario ha otorgado el permiso WRITE_STORAGE // public void checkPermission (int requestCode) {switch (requestCode) {case WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (this, Manifest.permission.WRITE_EXTERNAL_STORAGE); // Si tenemos acceso al almacenamiento externo ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//...call selectPicture, que inicia una actividad donde el usuario puede seleccionar una imagen // selectPicture (); // Si no se ha otorgado el permiso, entonces ... //} else {//... solicite el permiso // ActivityCompat.requestPermissions (esto, nueva Cadena {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode); } rotura; }} private void selectPicture () {photo = MyHelper.createTempFile (foto); Intención intención = nueva intención (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // Iniciar una actividad donde el usuario puede elegir una imagen // startActivityForResult (intento, SELECT_PHOTO); }}

En este punto, su proyecto debería estar quejándose de que no puede resolver MyHelper.createTempFile. ¡Implementemos esto ahora!

Cambiar el tamaño de las imágenes con createTempFile

Cree una nueva clase "MyHelper". En esta clase, vamos a cambiar el tamaño de la imagen elegida por el usuario, lista para ser procesada por la API de reconocimiento de texto.

importar android.graphics.Bitmap; importar android.graphics.BitmapFactory; importar android.content.Context; importar android.database.Cursor; importar android.os.Environment; importar android.widget.ImageView; importar android.provider.MediaStore; importar android.net.Uri; importar android.graphics.BitmapFactory.decodeFile estático; importar android.graphics.BitmapFactory.decodeStream estático; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class MyHelper {public static String getPath (Context context, Uri uri) {String path = ""; Proyección de cadena = {MediaStore.Images.Media.DATA}; Cursor cursor = context.getContentResolver (). Query (uri, proyección, nulo, nulo, nulo); int column_index; if (cursor! = null) {column_index = cursor.getColumnIndexOrThrow (MediaStore.Images.Media.DATA); cursor.moveToFirst (); ruta = cursor.getString (column_index); cursor.close (); } vía de retorno; } Archivo público estático createTempFile (archivo) {Directorio de archivos = nuevo archivo (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication"); if (! directorio.existe () ||! directorio.isDirectorio ()) {directorio.mkdirs (); } if (archivo == nulo) {archivo = archivo nuevo (directorio, "orig.jpg"); } archivo de retorno; } mapa de bits público estático resizePhoto (archivo de imagen de archivo, contexto de contexto, Uri uri, vista de ImageView) {BitmapFactory.Options newOptions = new BitmapFactory.Options (); try {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 ()); return compressPhoto (imageFile, BitmapFactory.decodeStream (context.getContentResolver (). openInputStream (uri), null, newOptions)); } catch (excepción FileNotFoundException) {exception.printStackTrace (); volver nulo; }} mapa de bits estático público resizePhoto (archivo de imagen de archivo, ruta de cadena, vista ImageView) {Opciones de BitmapFactory.Options = nuevo BitmapFactory.Options (); decodeFile (ruta, opciones); int photoHeight = options.outHeight; int photoWidth = options.outWidth; options.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); return compressPhoto (imageFile, BitmapFactory.decodeFile (ruta, opciones)); } mapa de bits estático privado compressPhoto (File photoFile, Bitmap bitmap) {try {FileOutputStream fOutput = new FileOutputStream (photoFile); bitmap.compress (Bitmap.CompressFormat.JPEG, 70, fOutput); fOutput.close (); } catch (excepción IOException) {exception.printStackTrace (); } regresar mapa de bits; }}

Establecer la imagen en un ImageView

A continuación, debemos implementar onActivityResult () en nuestra clase MainActivity y configurar la imagen elegida por el usuario en nuestro ImageView.

importar android.graphics.Bitmap; importar android.os.Bundle; importar android.widget.ImageView; importar android.content.Intent; importar android.widget.TextView; importar android.net.Uri; clase pública MainActivity extiende BaseActivity {mapa de bits privado myBitmap; ImageView privado myImageView; TextView privado myTextView; @Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); } @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); descanso; caso SELECT_PHOTO: Uri dataUri = data.getData (); Ruta de cadena = MyHelper.getPath (this, dataUri); if (ruta == nulo) {myBitmap = MyHelper.resizePhoto (foto, esto, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (foto, ruta, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } rotura; }}}}

Ejecute este proyecto en un dispositivo Android físico o AVD, y haga clic en el icono de la barra de acción. Cuando se le solicite, otorgue el permiso WRITE_STORAGE y elija una imagen de la galería; esta imagen ahora debería mostrarse en la IU de su aplicación

Ahora que hemos sentado las bases, ¡estamos listos para comenzar a extraer texto!

Enseñar una aplicación para reconocer texto

Quiero activar el reconocimiento de texto en respuesta a un evento de clic, por lo que debemos implementar un OnClickListener:

importar android.graphics.Bitmap; importar android.os.Bundle; importar android.widget.ImageView; importar android.content.Intent; importar android.widget.TextView; importar android.view.View; importar android.net.Uri; MainActivity de clase pública extiende los implementos de BaseActivity View.OnClickListener {mapa de bits privado myBitmap; ImageView privado myImageView; TextView privado myTextView; @Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (esto); } @Override public void onClick (Ver vista) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {// Implementaremos runTextRecog en el siguiente paso // runTextRecog (); } rotura; }}

ML Kit solo puede procesar imágenes cuando están en el formato FirebaseVisionImage, por lo que debemos convertir nuestra imagen en un objeto FirebaseVisionImage. Puede crear una FirebaseVisionImage desde un mapa de bits, media.Image, ByteBuffer o una matriz de bytes. Dado que estamos trabajando con mapas de bits, debemos llamar al método de utilidad fromBitmap () de la clase FirebaseVisionImage y pasarlo a nuestro mapa de bits.

privado vacío runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap);

ML Kit tiene diferentes clases de detectores para cada una de sus operaciones de reconocimiento de imágenes. Para el texto, necesitamos usar la clase FirebaseVisionTextDetector, que realiza el reconocimiento óptico de caracteres (OCR) en una imagen.

Creamos una instancia de FirebaseVisionTextDetector, usando getVisionTextDetector:

Detector FirebaseVisionTextDetector = FirebaseVision.getInstance (). GetVisionTextDetector ();

Luego, debemos verificar el FirebaseVisionImage para el texto, llamando al método detectInImage () y pasándole el objeto FirebaseVisionImage. También necesitamos implementar devoluciones de llamada onSuccess y onFailure, además de los oyentes correspondientes para que nuestra aplicación sea notificada cuando los resultados estén disponibles.

detector.detectInImage (imagen) .addOnSuccessListener (nuevo OnSuccessListener() {@Override // To do //}}). AddOnFailureListener (new OnFailureListener () {@Override public void onFailure (excepción de excepción @NonNull) {// La tarea falló con una excepción //}}); }

Si esta operación falla, mostraré un brindis, pero si la operación es exitosa, llamaré a processExtractedText con la respuesta.

En este punto, mi código de detección de texto se ve así:

// Crear una FirebaseVisionImage // privado void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); // Cree una instancia de FirebaseVisionCloudTextDetector // FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). GetVisionTextDetector (); // Registre un OnSuccessListener // detector.detectInImage (imagen) .addOnSuccessListener (nuevo OnSuccessListener() {@Override // Implemente la devolución de llamada onSuccess // public void onSuccess (textos de FirebaseVisionText) {// Llame a processExtractedText con la respuesta // processExtractedText (textos); }}). addOnFailureListener (new OnFailureListener () {@Override // Implemente el calculo onFailure // public void onFailure (excepción de excepción @NonNull) {Toast.makeText (MainActivity.this, "Exception", Toast.LENGTH_LONG) .show (Toast.LENGTH_LONG) .show (Toast.LENGTH_LONG) .show ( );}}); }

Cada vez que nuestra aplicación recibe una notificación onSuccess, necesitamos analizar los resultados.

Un objeto FirebaseVisionText puede contener elementos, líneas y bloques, donde cada bloque normalmente equivale a un solo párrafo de texto. Si FirebaseVisionText devuelve 0 bloques, mostraremos la cadena "no_text", pero si contiene uno o más bloques, mostraremos el texto recuperado como parte de nuestro TextView.

proceso vacío privadoExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (nulo); if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text); regreso; } para (bloque FirebaseVisionText.Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Aquí está el código MainActivity completado:

importar android.graphics.Bitmap; importar android.os.Bundle; importar android.widget.ImageView; importar android.content.Intent; importar android.widget.TextView; importar android.widget.Toast; importar android.view.View; importar android.net.Uri; importar android.support.annotation.NonNull; importar com.google.firebase.ml.vision.common.FirebaseVisionImage; importar com.google.firebase.ml.vision.text.FirebaseVisionText; importar com.google.firebase.ml.vision.text.FirebaseVisionTextDetector; importar com.google.firebase.ml.vision.FirebaseVision; importar com.google.android.gms.tasks.OnSuccessListener; importar com.google.android.gms.tasks.OnFailureListener; MainActivity de clase pública extiende los implementos de BaseActivity View.OnClickListener {mapa de bits privado myBitmap; ImageView privado myImageView; TextView privado myTextView; @Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (esto); } @Override public void onClick (Ver vista) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {runTextRecog (); } rotura; }} @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); descanso; caso SELECT_PHOTO: Uri dataUri = data.getData (); Ruta de cadena = MyHelper.getPath (this, dataUri); if (ruta == nulo) {myBitmap = MyHelper.resizePhoto (foto, esto, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (foto, ruta, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } rotura; }}} privado vacío runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); Detector FirebaseVisionTextDetector = FirebaseVision.getInstance (). GetVisionTextDetector (); detector.detectInImage (imagen) .addOnSuccessListener (nuevo OnSuccessListener() {@Override public void onSuccess (textos de FirebaseVisionText) {processExtractedText (textos); }}). addOnFailureListener (new OnFailureListener () {@Override public void onFailure (@NonNull Exception except) {Toast.makeText (MainActivity.this, "Exception", Toast.LENGTH_LONG) .show ();}}); } proceso vacío privadoExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (nulo); if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text); regreso; } para (bloque FirebaseVisionText.Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Probar el proyecto

¡Ahora es el momento de ver el Reconocimiento de texto de ML Kit en acción! Instale este proyecto en un dispositivo Android o AVD, elija una imagen de la galería y luego toque el botón "Verificar el texto". La aplicación debe responder extrayendo todo el texto de la imagen y luego mostrándolo en un TextView.

Tenga en cuenta que dependiendo del tamaño de su imagen y la cantidad de texto que contiene, es posible que deba desplazarse para ver todo el texto extraído.

También puede descargar el proyecto completado desde GitHub.

Terminando

Ahora sabe cómo detectar y extraer texto de una imagen, utilizando ML Kit.

La API de reconocimiento de texto es solo una parte del Kit ML. Este SDK también ofrece escaneo de códigos de barras, detección de rostros, etiquetado de imágenes y reconocimiento de puntos de referencia, con planes para agregar más API para casos de uso móvil comunes, incluyendo Smart Reply y una API de contorno de cara de alta densidad.

¿Qué API de ML Kit te interesa más probar? ¡Háganos saber en los comentarios a continuación!

Actualización: 5 de junio de 2019 a la 4:15 p.m. ET: La cuarta vita previa para dearrolladore de Android Q e lanzó hoy. Entre lo mucho ajute en eta verión, Google volvió a agregar ...

El Redmi Note 8 Pro etá en la carrera por el mejor teléfono económico del año baado únicamente en la hoja de epecificacione. Entre la batería grande y la configuració...

Cuota