Puedes usar el AA de Firebase para reconocer texto en imágenes. AA de Firebase tiene una API de uso general adecuada para reconocer texto en imágenes, como el de una señal de tránsito, y una API optimizada para reconocer el texto de documentos.
Antes de comenzar
- Si aún no lo hiciste, agrega Firebase a tu proyecto de Android.
-
En el archivo de Gradle (generalmente
<project>/<app-module>/build.gradle.kts
o<project>/<app-module>/build.gradle
) del módulo (a nivel de app), agrega la dependencia de la biblioteca de Android para Firebase ML Vision. Te recomendamos usar la BoM de Firebase para Android para controlar las versiones de las bibliotecas.dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:32.3.1")) // Add the dependency for the Firebase ML Vision library // When using the BoM, you don't specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-ml-vision' }
Si usas la BoM de Firebase para Android, tu app siempre utilizará versiones compatibles de las bibliotecas de Firebase para Android.
(Alternativa) Agrega dependencias de la biblioteca de Firebase sin usar la BoM
Si eliges no usar la BoM de Firebase, debes especificar cada versión de la biblioteca de Firebase en su línea de dependencia.
Ten en cuenta que, si usas múltiples bibliotecas de Firebase en tu app, es muy recomendable que utilices la BoM para administrar las versiones de las bibliotecas y así poder garantizar que todas las versiones sean compatibles.
dependencies { // Add the dependency for the Firebase ML Vision library // When NOT using the BoM, you must specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-ml-vision:24.1.0' }
-
Si aún no habilitaste las APIs de Cloud en tu proyecto, hazlo de la siguiente manera:
- Abre la página de APIs de AA de Firebase de Firebase console.
-
Si todavía no actualizaste tu proyecto a un plan de precios Blaze, haz clic en Actualizar para hacerlo (se te pedirá que realices la actualización únicamente si tu proyecto no está en el plan Blaze).
Solo los proyectos con un plan Blaze pueden usar las APIs de Cloud.
- Si las APIs de Cloud no están habilitadas, haz clic en Habilitar las APIs de Cloud.
Ya estás listo para comenzar a reconocer texto en imágenes.
Lineamientos para imágenes de entrada
-
Para que AA de Firebase reconozca con precisión el texto, las imágenes de entrada deben contener texto que se represente con datos de píxeles suficientes. Lo ideal para el texto latino es que cada carácter sea de al menos 16 × 16 píxeles. En el caso del texto en chino, japonés y coreano, cada carácter debe ser de 24 × 24 píxeles. Generalmente, para todos los idiomas, no se obtiene un beneficio de exactitud cuando el tamaño de los caracteres es superior a 24 × 24 píxeles.
Por ejemplo, una imagen de 640 × 480 puede funcionar bien para escanear una tarjeta de presentación que ocupa todo el ancho de la imagen. Para escanear un documento impreso en tamaño de papel carta, es posible que se requiera una imagen de 720 × 1,280 píxeles.
-
Un enfoque de imagen deficiente puede afectar la exactitud del reconocimiento de texto. Si no obtienes resultados aceptables, intenta pedirle al usuario que vuelva a capturar la imagen.
Reconoce texto en imágenes
Para reconocer texto en una imagen, ejecuta el reconocedor de texto como se describe a continuación.
1. Ejecuta el reconocedor de texto
Para reconocer texto en una imagen, crea un objetoFirebaseVisionImage
a partir de un Bitmap
, una media.Image
, un ByteBuffer
, un array de bytes o un archivo ubicado en el dispositivo. Luego, pasa el objeto FirebaseVisionImage
al método processImage
de FirebaseVisionTextRecognizer
.
Crea un objeto
FirebaseVisionImage
a partir de tu imagen.-
Para crear un objeto
FirebaseVisionImage
a partir de un objetomedia.Image
, como cuando se captura una imagen con la cámara de un dispositivo, pasa el objetomedia.Image
y la rotación de la imagen aFirebaseVisionImage.fromMediaImage()
.Si usas la biblioteca CameraX, las clases
OnImageCapturedListener
yImageAnalysis.Analyzer
calculan el valor de rotación por ti, por lo que solo tienes que convertir la rotación en una de las constantesROTATION_
del AA de Firebase antes de llamar aFirebaseVisionImage.fromMediaImage()
:Kotlin+KTX
private class YourImageAnalyzer : ImageAnalysis.Analyzer { private fun degreesToFirebaseRotation(degrees: Int): Int = when(degrees) { 0 -> FirebaseVisionImageMetadata.ROTATION_0 90 -> FirebaseVisionImageMetadata.ROTATION_90 180 -> FirebaseVisionImageMetadata.ROTATION_180 270 -> FirebaseVisionImageMetadata.ROTATION_270 else -> throw Exception("Rotation must be 0, 90, 180, or 270.") } override fun analyze(imageProxy: ImageProxy?, degrees: Int) { val mediaImage = imageProxy?.image val imageRotation = degreesToFirebaseRotation(degrees) if (mediaImage != null) { val image = FirebaseVisionImage.fromMediaImage(mediaImage, imageRotation) // Pass image to an ML Vision API // ... } } }
Java
private class YourAnalyzer implements ImageAnalysis.Analyzer { private int degreesToFirebaseRotation(int degrees) { switch (degrees) { case 0: return FirebaseVisionImageMetadata.ROTATION_0; case 90: return FirebaseVisionImageMetadata.ROTATION_90; case 180: return FirebaseVisionImageMetadata.ROTATION_180; case 270: return FirebaseVisionImageMetadata.ROTATION_270; default: throw new IllegalArgumentException( "Rotation must be 0, 90, 180, or 270."); } } @Override public void analyze(ImageProxy imageProxy, int degrees) { if (imageProxy == null || imageProxy.getImage() == null) { return; } Image mediaImage = imageProxy.getImage(); int rotation = degreesToFirebaseRotation(degrees); FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation); // Pass image to an ML Vision API // ... } }
Si no usas una biblioteca de cámaras que te proporcione la rotación de la imagen, puedes calcularla a partir de la rotación del dispositivo y la orientación del sensor de la cámara en el dispositivo:
Kotlin+KTX
private val ORIENTATIONS = SparseIntArray() init { ORIENTATIONS.append(Surface.ROTATION_0, 90) ORIENTATIONS.append(Surface.ROTATION_90, 0) ORIENTATIONS.append(Surface.ROTATION_180, 270) ORIENTATIONS.append(Surface.ROTATION_270, 180) } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Throws(CameraAccessException::class) private fun getRotationCompensation(cameraId: String, activity: Activity, context: Context): Int { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. val deviceRotation = activity.windowManager.defaultDisplay.rotation var rotationCompensation = ORIENTATIONS.get(deviceRotation) // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. val cameraManager = context.getSystemService(CAMERA_SERVICE) as CameraManager val sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION)!! rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360 // Return the corresponding FirebaseVisionImageMetadata rotation value. val result: Int when (rotationCompensation) { 0 -> result = FirebaseVisionImageMetadata.ROTATION_0 90 -> result = FirebaseVisionImageMetadata.ROTATION_90 180 -> result = FirebaseVisionImageMetadata.ROTATION_180 270 -> result = FirebaseVisionImageMetadata.ROTATION_270 else -> { result = FirebaseVisionImageMetadata.ROTATION_0 Log.e(TAG, "Bad rotation value: $rotationCompensation") } } return result }
Java
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 0); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 180); } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private int getRotationCompensation(String cameraId, Activity activity, Context context) throws CameraAccessException { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int rotationCompensation = ORIENTATIONS.get(deviceRotation); // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE); int sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION); rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360; // Return the corresponding FirebaseVisionImageMetadata rotation value. int result; switch (rotationCompensation) { case 0: result = FirebaseVisionImageMetadata.ROTATION_0; break; case 90: result = FirebaseVisionImageMetadata.ROTATION_90; break; case 180: result = FirebaseVisionImageMetadata.ROTATION_180; break; case 270: result = FirebaseVisionImageMetadata.ROTATION_270; break; default: result = FirebaseVisionImageMetadata.ROTATION_0; Log.e(TAG, "Bad rotation value: " + rotationCompensation); } return result; }
Luego, pasa el objeto
media.Image
y el valor de rotación aFirebaseVisionImage.fromMediaImage()
:Kotlin+KTX
val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);
- Para crear un objeto
FirebaseVisionImage
a partir de un URI de archivo, pasa el contexto de la app y el URI de archivo aFirebaseVisionImage.fromFilePath()
. Esto es útil cuando usas un intentACTION_GET_CONTENT
para solicitarle al usuario que seleccione una imagen de su app de galería.Kotlin+KTX
val image: FirebaseVisionImage try { image = FirebaseVisionImage.fromFilePath(context, uri) } catch (e: IOException) { e.printStackTrace() }
Java
FirebaseVisionImage image; try { image = FirebaseVisionImage.fromFilePath(context, uri); } catch (IOException e) { e.printStackTrace(); }
- Para crear un objeto
FirebaseVisionImage
a partir de unByteBuffer
o un array de bytes, primero calcula la rotación de la imagen como se describió anteriormente para la entradamedia.Image
.Luego, crea un objeto
FirebaseVisionImageMetadata
que contenga la altura, el ancho, el formato de codificación de color y la rotación de la imagen:Kotlin+KTX
val metadata = FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build()
Java
FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build();
Usa el búfer o array, y el objeto de metadatos, para crear un objeto
FirebaseVisionImage
:Kotlin+KTX
val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata) // Or: val image = FirebaseVisionImage.fromByteArray(byteArray, metadata)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata); // Or: FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);
- Para crear un objeto
FirebaseVisionImage
a partir de un objetoBitmap
, haz lo siguiente:Kotlin+KTX
val image = FirebaseVisionImage.fromBitmap(bitmap)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
Bitmap
debe estar en posición vertical, sin que sea necesario rotarla.
-
Obtén una instancia de
FirebaseVisionTextRecognizer
.Kotlin+KTX
val detector = FirebaseVision.getInstance().cloudTextRecognizer // Or, to change the default settings: // val detector = FirebaseVision.getInstance().getCloudTextRecognizer(options)
// Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages val options = FirebaseVisionCloudTextRecognizerOptions.Builder() .setLanguageHints(listOf("en", "hi")) .build()
Java
FirebaseVisionTextRecognizer detector = FirebaseVision.getInstance() .getCloudTextRecognizer(); // Or, to change the default settings: // FirebaseVisionTextRecognizer detector = FirebaseVision.getInstance() // .getCloudTextRecognizer(options);
// Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages FirebaseVisionCloudTextRecognizerOptions options = new FirebaseVisionCloudTextRecognizerOptions.Builder() .setLanguageHints(Arrays.asList("en", "hi")) .build();
Por último, pasa la imagen al método
processImage
:Kotlin+KTX
val result = detector.processImage(image) .addOnSuccessListener { firebaseVisionText -> // Task completed successfully // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
Java
Task<FirebaseVisionText> result = detector.processImage(image) .addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() { @Override public void onSuccess(FirebaseVisionText firebaseVisionText) { // Task completed successfully // ... } }) .addOnFailureListener( new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } });
2. Extrae texto de bloques de texto reconocido
Si la operación de reconocimiento de texto se ejecuta correctamente, se pasará un objetoFirebaseVisionText
al objeto de escucha que detecta el resultado correcto. Un objeto FirebaseVisionText
contiene el texto completo reconocido en la imagen y cero o más objetos TextBlock
.
Cada TextBlock
representa un bloque rectangular de texto que contiene cero o más objetos Line
. Cada objeto Line
contiene cero o más objetos Element
que representan palabras y entidades similares (fechas, números, etcétera).
Para cada objeto TextBlock
, Line
y Element
, puedes obtener el texto reconocido en la región y las coordenadas que limitan la región.
Por ejemplo:
Kotlin+KTX
val resultText = result.text for (block in result.textBlocks) { val blockText = block.text val blockConfidence = block.confidence val blockLanguages = block.recognizedLanguages val blockCornerPoints = block.cornerPoints val blockFrame = block.boundingBox for (line in block.lines) { val lineText = line.text val lineConfidence = line.confidence val lineLanguages = line.recognizedLanguages val lineCornerPoints = line.cornerPoints val lineFrame = line.boundingBox for (element in line.elements) { val elementText = element.text val elementConfidence = element.confidence val elementLanguages = element.recognizedLanguages val elementCornerPoints = element.cornerPoints val elementFrame = element.boundingBox } } }
Java
String resultText = result.getText(); for (FirebaseVisionText.TextBlock block: result.getTextBlocks()) { String blockText = block.getText(); Float blockConfidence = block.getConfidence(); List<RecognizedLanguage> blockLanguages = block.getRecognizedLanguages(); Point[] blockCornerPoints = block.getCornerPoints(); Rect blockFrame = block.getBoundingBox(); for (FirebaseVisionText.Line line: block.getLines()) { String lineText = line.getText(); Float lineConfidence = line.getConfidence(); List<RecognizedLanguage> lineLanguages = line.getRecognizedLanguages(); Point[] lineCornerPoints = line.getCornerPoints(); Rect lineFrame = line.getBoundingBox(); for (FirebaseVisionText.Element element: line.getElements()) { String elementText = element.getText(); Float elementConfidence = element.getConfidence(); List<RecognizedLanguage> elementLanguages = element.getRecognizedLanguages(); Point[] elementCornerPoints = element.getCornerPoints(); Rect elementFrame = element.getBoundingBox(); } } }
Próximos pasos
- Antes de implementar en producción una app que usa una API de Cloud, debes realizar algunos pasos adicionales para prevenir y mitigar el efecto del acceso no autorizado a la API.
Reconoce texto en imágenes de documentos
Para reconocer el texto de un documento, configura y ejecuta el reconocedor de texto en documentos como se describe a continuación.
La API de reconocimiento de texto en documentos, que se describe a continuación, proporciona una interfaz diseñada para facilitar el trabajo con imágenes en documentos. Sin embargo,
si prefieres la interfaz que proporciona la API de FirebaseVisionTextRecognizer
,
puedes usarla a fin de escanear documentos mediante la configuración del reconocedor
de texto en la nube para que use el modelo para densidad de texto.
Para usar la API de reconocimiento de texto en documentos, haz lo siguiente:
1. Ejecuta el reconocedor de texto
Para reconocer texto en una imagen, crea un objetoFirebaseVisionImage
a partir de un Bitmap
, una media.Image
, un ByteBuffer
, un array de bytes o un archivo en el dispositivo.
Luego, pasa el objeto FirebaseVisionImage
al método processImage
de FirebaseVisionDocumentTextRecognizer
.
Crea un objeto
FirebaseVisionImage
a partir de tu imagen.-
Para crear un objeto
FirebaseVisionImage
a partir de un objetomedia.Image
, como cuando se captura una imagen con la cámara de un dispositivo, pasa el objetomedia.Image
y la rotación de la imagen aFirebaseVisionImage.fromMediaImage()
.Si usas la biblioteca CameraX, las clases
OnImageCapturedListener
yImageAnalysis.Analyzer
calculan el valor de rotación por ti, por lo que solo tienes que convertir la rotación en una de las constantesROTATION_
del AA de Firebase antes de llamar aFirebaseVisionImage.fromMediaImage()
:Kotlin+KTX
private class YourImageAnalyzer : ImageAnalysis.Analyzer { private fun degreesToFirebaseRotation(degrees: Int): Int = when(degrees) { 0 -> FirebaseVisionImageMetadata.ROTATION_0 90 -> FirebaseVisionImageMetadata.ROTATION_90 180 -> FirebaseVisionImageMetadata.ROTATION_180 270 -> FirebaseVisionImageMetadata.ROTATION_270 else -> throw Exception("Rotation must be 0, 90, 180, or 270.") } override fun analyze(imageProxy: ImageProxy?, degrees: Int) { val mediaImage = imageProxy?.image val imageRotation = degreesToFirebaseRotation(degrees) if (mediaImage != null) { val image = FirebaseVisionImage.fromMediaImage(mediaImage, imageRotation) // Pass image to an ML Vision API // ... } } }
Java
private class YourAnalyzer implements ImageAnalysis.Analyzer { private int degreesToFirebaseRotation(int degrees) { switch (degrees) { case 0: return FirebaseVisionImageMetadata.ROTATION_0; case 90: return FirebaseVisionImageMetadata.ROTATION_90; case 180: return FirebaseVisionImageMetadata.ROTATION_180; case 270: return FirebaseVisionImageMetadata.ROTATION_270; default: throw new IllegalArgumentException( "Rotation must be 0, 90, 180, or 270."); } } @Override public void analyze(ImageProxy imageProxy, int degrees) { if (imageProxy == null || imageProxy.getImage() == null) { return; } Image mediaImage = imageProxy.getImage(); int rotation = degreesToFirebaseRotation(degrees); FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation); // Pass image to an ML Vision API // ... } }
Si no usas una biblioteca de cámaras que te proporcione la rotación de la imagen, puedes calcularla a partir de la rotación del dispositivo y la orientación del sensor de la cámara en el dispositivo:
Kotlin+KTX
private val ORIENTATIONS = SparseIntArray() init { ORIENTATIONS.append(Surface.ROTATION_0, 90) ORIENTATIONS.append(Surface.ROTATION_90, 0) ORIENTATIONS.append(Surface.ROTATION_180, 270) ORIENTATIONS.append(Surface.ROTATION_270, 180) } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Throws(CameraAccessException::class) private fun getRotationCompensation(cameraId: String, activity: Activity, context: Context): Int { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. val deviceRotation = activity.windowManager.defaultDisplay.rotation var rotationCompensation = ORIENTATIONS.get(deviceRotation) // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. val cameraManager = context.getSystemService(CAMERA_SERVICE) as CameraManager val sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION)!! rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360 // Return the corresponding FirebaseVisionImageMetadata rotation value. val result: Int when (rotationCompensation) { 0 -> result = FirebaseVisionImageMetadata.ROTATION_0 90 -> result = FirebaseVisionImageMetadata.ROTATION_90 180 -> result = FirebaseVisionImageMetadata.ROTATION_180 270 -> result = FirebaseVisionImageMetadata.ROTATION_270 else -> { result = FirebaseVisionImageMetadata.ROTATION_0 Log.e(TAG, "Bad rotation value: $rotationCompensation") } } return result }
Java
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 0); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 180); } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private int getRotationCompensation(String cameraId, Activity activity, Context context) throws CameraAccessException { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int rotationCompensation = ORIENTATIONS.get(deviceRotation); // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE); int sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION); rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360; // Return the corresponding FirebaseVisionImageMetadata rotation value. int result; switch (rotationCompensation) { case 0: result = FirebaseVisionImageMetadata.ROTATION_0; break; case 90: result = FirebaseVisionImageMetadata.ROTATION_90; break; case 180: result = FirebaseVisionImageMetadata.ROTATION_180; break; case 270: result = FirebaseVisionImageMetadata.ROTATION_270; break; default: result = FirebaseVisionImageMetadata.ROTATION_0; Log.e(TAG, "Bad rotation value: " + rotationCompensation); } return result; }
Luego, pasa el objeto
media.Image
y el valor de rotación aFirebaseVisionImage.fromMediaImage()
:Kotlin+KTX
val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);
- Para crear un objeto
FirebaseVisionImage
a partir de un URI de archivo, pasa el contexto de la app y el URI de archivo aFirebaseVisionImage.fromFilePath()
. Esto es útil cuando usas un intentACTION_GET_CONTENT
para solicitarle al usuario que seleccione una imagen de su app de galería.Kotlin+KTX
val image: FirebaseVisionImage try { image = FirebaseVisionImage.fromFilePath(context, uri) } catch (e: IOException) { e.printStackTrace() }
Java
FirebaseVisionImage image; try { image = FirebaseVisionImage.fromFilePath(context, uri); } catch (IOException e) { e.printStackTrace(); }
- Para crear un objeto
FirebaseVisionImage
a partir de unByteBuffer
o un array de bytes, primero calcula la rotación de la imagen como se describió anteriormente para la entradamedia.Image
.Luego, crea un objeto
FirebaseVisionImageMetadata
que contenga la altura, el ancho, el formato de codificación de color y la rotación de la imagen:Kotlin+KTX
val metadata = FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build()
Java
FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build();
Usa el búfer o array, y el objeto de metadatos, para crear un objeto
FirebaseVisionImage
:Kotlin+KTX
val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata) // Or: val image = FirebaseVisionImage.fromByteArray(byteArray, metadata)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata); // Or: FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);
- Para crear un objeto
FirebaseVisionImage
a partir de un objetoBitmap
, haz lo siguiente:Kotlin+KTX
val image = FirebaseVisionImage.fromBitmap(bitmap)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
Bitmap
debe estar en posición vertical, sin que sea necesario rotarla.
-
Obtén una instancia de
FirebaseVisionDocumentTextRecognizer
:Kotlin+KTX
val detector = FirebaseVision.getInstance() .cloudDocumentTextRecognizer
// Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages val options = FirebaseVisionCloudDocumentRecognizerOptions.Builder() .setLanguageHints(listOf("en", "hi")) .build() val detector = FirebaseVision.getInstance() .getCloudDocumentTextRecognizer(options)
Java
FirebaseVisionDocumentTextRecognizer detector = FirebaseVision.getInstance() .getCloudDocumentTextRecognizer();
// Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages FirebaseVisionCloudDocumentRecognizerOptions options = new FirebaseVisionCloudDocumentRecognizerOptions.Builder() .setLanguageHints(Arrays.asList("en", "hi")) .build(); FirebaseVisionDocumentTextRecognizer detector = FirebaseVision.getInstance() .getCloudDocumentTextRecognizer(options);
Por último, pasa la imagen al método
processImage
:Kotlin+KTX
detector.processImage(myImage) .addOnSuccessListener { firebaseVisionDocumentText -> // Task completed successfully // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
Java
detector.processImage(myImage) .addOnSuccessListener(new OnSuccessListener<FirebaseVisionDocumentText>() { @Override public void onSuccess(FirebaseVisionDocumentText result) { // Task completed successfully // ... } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } });
2. Extrae texto de bloques de texto reconocido
Si la operación de reconocimiento de texto se ejecuta correctamente, se mostrará un objeto FirebaseVisionDocumentText
. El objeto FirebaseVisionDocumentText
contiene todo el texto reconocido en la imagen y una jerarquía de objetos que refleja la estructura del documento reconocido:
FirebaseVisionDocumentText.Block
FirebaseVisionDocumentText.Paragraph
FirebaseVisionDocumentText.Word
FirebaseVisionDocumentText.Symbol
Para cada objeto Block
, Paragraph
, Word
y Symbol
, puedes obtener el texto reconocido en la región y las coordenadas que limitan la región.
Por ejemplo:
Kotlin+KTX
val resultText = result.text for (block in result.blocks) { val blockText = block.text val blockConfidence = block.confidence val blockRecognizedLanguages = block.recognizedLanguages val blockFrame = block.boundingBox for (paragraph in block.paragraphs) { val paragraphText = paragraph.text val paragraphConfidence = paragraph.confidence val paragraphRecognizedLanguages = paragraph.recognizedLanguages val paragraphFrame = paragraph.boundingBox for (word in paragraph.words) { val wordText = word.text val wordConfidence = word.confidence val wordRecognizedLanguages = word.recognizedLanguages val wordFrame = word.boundingBox for (symbol in word.symbols) { val symbolText = symbol.text val symbolConfidence = symbol.confidence val symbolRecognizedLanguages = symbol.recognizedLanguages val symbolFrame = symbol.boundingBox } } } }
Java
String resultText = result.getText(); for (FirebaseVisionDocumentText.Block block: result.getBlocks()) { String blockText = block.getText(); Float blockConfidence = block.getConfidence(); List<RecognizedLanguage> blockRecognizedLanguages = block.getRecognizedLanguages(); Rect blockFrame = block.getBoundingBox(); for (FirebaseVisionDocumentText.Paragraph paragraph: block.getParagraphs()) { String paragraphText = paragraph.getText(); Float paragraphConfidence = paragraph.getConfidence(); List<RecognizedLanguage> paragraphRecognizedLanguages = paragraph.getRecognizedLanguages(); Rect paragraphFrame = paragraph.getBoundingBox(); for (FirebaseVisionDocumentText.Word word: paragraph.getWords()) { String wordText = word.getText(); Float wordConfidence = word.getConfidence(); List<RecognizedLanguage> wordRecognizedLanguages = word.getRecognizedLanguages(); Rect wordFrame = word.getBoundingBox(); for (FirebaseVisionDocumentText.Symbol symbol: word.getSymbols()) { String symbolText = symbol.getText(); Float symbolConfidence = symbol.getConfidence(); List<RecognizedLanguage> symbolRecognizedLanguages = symbol.getRecognizedLanguages(); Rect symbolFrame = symbol.getBoundingBox(); } } } }
Próximos pasos
- Antes de implementar en producción una app que usa una API de Cloud, debes realizar algunos pasos adicionales para prevenir y mitigar el efecto del acceso no autorizado a la API.