<div class="wp-block-buttons is-content-justification-center is-layout-flex wp-block-buttons-is-layout-flex"> 
<div>This post is about, how to recognize text in images using <span style="color: #0000ff;"><strong>Google ML Kit Text Recognition API</strong></span> in Android application with the help of a simple demo app.</div> 
<div>In the Demo App, we will recognize and extract text from images placed in the app assets and draw the bounding box around each element (word).</div> 
</div> 
<div> </div> 
<div class="wp-block-buttons is-content-justification-center"> 
<div class="wp-block-button"><a class="wp-block-button__link has-white-color has-text-color has-background" style="background-color: #13025e;" href="https://github.com/arunk7839/TextRecognitionExp"><strong>DOWNLOAD CODE</strong></a></div> 
</div> 
<p><amp-youtube layout="responsive" width="1200" height="675" data-videoid="3MCerJYS0aI" title="Recognize text in images with ML Kit on Android"><a placeholder href="https://youtu.be/3MCerJYS0aI"><img src="https://i.ytimg.com/vi/3MCerJYS0aI/hqdefault.jpg" layout="fill" object-fit="cover" alt="Recognize text in images with ML Kit on Android"></a></amp-youtube></p> 
<div> 
<h4><span style="color: #000080;"><strong>ML Kit’s Text Recognition API</strong></span></h4> 
<p>ML Kit’s Text Recognition API recognize and extract text from images. The Text Recognizer segments the text into <span style="color: #0000ff;"><strong>blocks ( paragraph or column ), lines, and elements( word )</strong></span>.</p> 
<h4><span style="color: #000080;"><strong>Creating new project</strong></span></h4> 
<p>Create a new project by going to <span style="color: #008000;"><strong>File ⇒ New Android Project</strong></span>, select <span style="color: #008000;"><strong>Empty</strong></span> Activity, provide app name, select language to <span style="color: #008000;"><strong>java</strong></span> and then finally click on <span style="color: #0000ff;"><strong>finish</strong></span>.</p> 
<h5><span style="color: #000080;"><strong>Adding Dependency</strong></span></h5> 
<p>Open build.gradle (Module: app) file and add the ML Kit’s Text Recognition API dependency inside the dependencies section:</p> 
<p><strong><span style="color: #0000ff;">build.gradle</span></strong></p> 
<pre>dependencies {<br /><strong><span style="color: #008000;"> implementation 'com.google.android.gms:play-services-mlkit-text-recognition:16.0.0'</span></strong><br />}</pre> 
<h5><span style="color: #000080;"><strong>Creating Layout File</strong></span></h5> 
<p>The<strong><span style="color: #008000;"> activity_main.xml</span></strong> layout file defines the UI of the application.</p> 
<p><strong><span style="color: #0000ff;">activity_main.xml</span></strong></p> 
<pre><;?xml version="1.0" encoding="utf-8"?>;<br /><;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> xmlns:app="http://schemas.android.com/apk/res-auto"<br /> xmlns:tools="http://schemas.android.com/tools"<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> tools:context=".MainActivity">;<br /><br /> <;ImageView<br /> android:id="@+id/image_view"<br /> android:layout_width="match_parent"<br /> android:layout_height="0dp"<br /> android:scaleType="fitStart"<br /> app:layout_constraintBottom_toTopOf="@+id/btn_find_text"<br /> app:layout_constraintLeft_toLeftOf="parent"<br /> app:layout_constraintRight_toRightOf="parent"<br /> app:layout_constraintTop_toTopOf="parent" />;<br /><br /> <;com.c1ctech.textrecognitionexp.GraphicOverlay<br /> android:id="@+id/graphic_overlay"<br /> android:layout_width="match_parent"<br /> android:layout_height="0dp"<br /> android:layout_alignParentStart="true"<br /> app:layout_constraintBottom_toBottomOf="@id/image_view"<br /> app:layout_constraintLeft_toLeftOf="@id/image_view"<br /> app:layout_constraintRight_toRightOf="@id/image_view"<br /> app:layout_constraintTop_toTopOf="@id/image_view" />;<br /><br /> <;Button<br /> android:id="@+id/btn_find_text"<br /> android:layout_width="wrap_content"<br /> android:layout_height="wrap_content"<br /> android:text="Find Text"<br /> android:layout_margin="10dp"<br /> app:layout_constraintBottom_toBottomOf="parent"<br /> app:layout_constraintLeft_toLeftOf="parent"<br /> app:layout_constraintRight_toRightOf="parent" />;<br /><br /><;/androidx.constraintlayout.widget.ConstraintLayout>;</pre> 
</div> 
<h5><strong><span style="color: #000080;">Recognize and extract text from image bitmap</span></strong></h5> 
<p>To recognize and extract text from the image bitmap, we have to follow the below steps: </p> 
<ul> 
<li>prepare input image using a bitmap.</li> 
<li>creating TextRecognizer instance.</li> 
<li>process the image. 
<ul> 
<li>If the text recognition operation succeeds, a <span style="color: #008000;"><strong>Text</strong></span> object is passed to the success listener.</li> 
<li>In case of error, an <span style="color: #008000;"><strong>exception</strong></span> is passed to the failure listener.</li> 
</ul> 
</li> 
</ul> 
<pre><span style="color: #008000;"><strong>//recognize and extract text from image bitmap</strong></span><br />private void runTextRecognition() {<br /><br /><strong><span style="color: #008000;"> //prepare input image using bitmap</span></strong><br /> InputImage image = InputImage.fromBitmap(mSelectedImage, 0);<br /><br /><span style="color: #008000;"><strong> //creating TextRecognizer instance</strong></span><br /> TextRecognizer recognizer = TextRecognition.getClient();<br /><br /><strong><span style="color: #008000;"> //process the image</span></strong><br /> recognizer.process(image)<br /> .addOnSuccessListener(<br /> new OnSuccessListener<;Text>;() {<br /> @Override<br /> public void onSuccess(Text texts) {<br /><strong><span style="color: #008000;"> //Task completed successfully</span></strong><br /> processTextRecognitionResult(texts);<br /> }<br /> })<br /> .addOnFailureListener(<br /> new OnFailureListener() {<br /> @Override<br /> public void onFailure(@NonNull Exception e) {<br /><span style="color: #008000;"><strong> // Task failed with an exception</strong></span><br /> e.printStackTrace();<br /> }<br /> });<br />}</pre> 
<h5><span style="color: #000080;"><strong>Extract text from blocks of recognized text</strong></span></h5> 
<p>A <span style="color: #0000ff;"><strong>Text</strong></span> object contains the full text recognized in the image and zero or more TextBlock objects.</p> 
<p><strong><span style="color: #0000ff;">TextBlock</span></strong> &#8211; represents a rectangular block of text, which contains zero or more Line objects.</p> 
<p><strong><span style="color: #0000ff;">Line</span></strong> &#8211; object contains zero or more Element objects.</p> 
<p><strong><span style="color: #0000ff;">Element</span></strong> &#8211; objects which represent words and word-like entities such as dates and numbers.</p>
<!-- WP QUADS Content Ad Plugin v. 2.0.98.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>
 
<pre>private void processTextRecognitionResult(Text texts) {<br /> List<;Text.TextBlock>; blocks = texts.getTextBlocks();<br /> if (blocks.size() == 0) {<br /> Toast.makeText(getApplicationContext(), "No text found", Toast.LENGTH_SHORT).show();<br /> return;<br /> }<br /> mGraphicOverlay.clear();<br /> for (Text.TextBlock block : texts.getTextBlocks()) {<br /> for (Text.Line line : block.getLines()) {<br /> for (Text.Element element : line.getElements()) {<br /><strong><span style="color: #008000;"> //draws the bounding box around the element.</span></strong><br /> GraphicOverlay.Graphic textGraphic = new TextGraphic(mGraphicOverlay, element);<br /> mGraphicOverlay.add(textGraphic);<br /> }<br /> }<br /> }<br />}</pre> 
<div> 
<h5><strong><span style="color: #000080;">Complete MainActivity Code</span></strong></h5> 
<p><strong><span style="color: #0000ff;">MainActivity.kt</span></strong></p> 
<pre>package com.c1ctech.textrecognitionexp;<br /><br />import androidx.annotation.NonNull;<br />import androidx.appcompat.app.AppCompatActivity;<br /><br />import android.content.Context;<br />import android.content.res.AssetManager;<br />import android.graphics.Bitmap;<br />import android.graphics.BitmapFactory;<br />import android.os.Bundle;<br />import android.view.View;<br />import android.widget.Button;<br />import android.widget.ImageView;<br />import android.widget.Toast;<br /><br />import com.google.android.gms.tasks.OnFailureListener;<br />import com.google.android.gms.tasks.OnSuccessListener;<br />import com.google.mlkit.vision.common.InputImage;<br />import com.google.mlkit.vision.text.Text;<br />import com.google.mlkit.vision.text.TextRecognition;<br />import com.google.mlkit.vision.text.TextRecognizer;<br /><br />import java.io.IOException;<br />import java.io.InputStream;<br />import java.util.List;<br /><br />public class MainActivity extends AppCompatActivity {<br /><br /> private ImageView mImageView;<br /> private Button mFindTextBtn;<br /> private Bitmap mSelectedImage;<br /> private GraphicOverlay mGraphicOverlay;<br /><br /> @Override<br /> protected void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.activity_main);<br /><br /> mImageView = findViewById(R.id.image_view);<br /><br /> mFindTextBtn = findViewById(R.id.btn_find_text);<br /><br /> mGraphicOverlay = findViewById(R.id.graphic_overlay);<br /><br /> mSelectedImage = getBitmapFromAsset(this, "page.png");<br /> mImageView.setImageBitmap(mSelectedImage);<br /><br /> mFindTextBtn.setOnClickListener(new View.OnClickListener() {<br /> @Override<br /> public void onClick(View v) {<br /><span style="color: #008000;"><strong> //if bitmap is not null</strong></span><br /> if (mSelectedImage != null) {<br /><strong><span style="color: #008000;"> //Creates a new bitmap, scaled from an existing bitmap</span></strong><br /> Bitmap resizedBitmap = createScaleFactorUsingBitmap(mSelectedImage);<br /><strong><span style="color: #008000;"> //setting new scaled bitmap in imageview</span></strong><br /> mImageView.setImageBitmap(resizedBitmap);<br /> mSelectedImage = resizedBitmap;<br /> }<br /> runTextRecognition();<br /> }<br /> });<br /><br /> }<br /><br /> private Bitmap createScaleFactorUsingBitmap(Bitmap mSelectedImage) {<br /><span style="color: #008000;"><strong> // Determine how much to scale down the image</strong></span><br /> float scaleFactor =<br /> Math.max(<br /> (float) mSelectedImage.getWidth() / (float) mImageView.getWidth(),<br /> (float) mSelectedImage.getHeight() / (float) mImageView.getHeight());<br /><br /> Bitmap resizedBitmap =<br /> Bitmap.createScaledBitmap(<br /> mSelectedImage,<br /> (int) (mSelectedImage.getWidth() / scaleFactor),<br /> (int) (mSelectedImage.getHeight() / scaleFactor),<br /> true);<br /><br /> return resizedBitmap;<br /> }<br /><br /><span style="color: #008000;"><strong> //recognize and extract text from image bitmap</strong></span><br /> private void runTextRecognition() {<br /><br /><strong><span style="color: #008000;"> //prepare input image using bitmap</span></strong><br /> InputImage image = InputImage.fromBitmap(mSelectedImage, 0);<br /><br /><span style="color: #008000;"><strong> //creating TextRecognizer instance</strong></span><br /> TextRecognizer recognizer = TextRecognition.getClient();<br /><br /><strong><span style="color: #008000;"> //process the image</span></strong><br /> recognizer.process(image)<br /> .addOnSuccessListener(<br /> new OnSuccessListener<;Text>;() {<br /> @Override<br /> public void onSuccess(Text texts) {<br /><strong><span style="color: #008000;"> //Task completed successfully.</span></strong><br /> processTextRecognitionResult(texts);<br /> }<br /> })<br /> .addOnFailureListener(<br /> new OnFailureListener() {<br /> @Override<br /> public void onFailure(@NonNull Exception e) {<br /><span style="color: #008000;"><strong> // Task failed with an exception</strong></span><br /> e.printStackTrace();<br /> }<br /> });<br /> }<br /><br /><br /><span style="color: #008000;"><strong> //perform operation on the full text recognized in the image.</strong></span><br /> private void processTextRecognitionResult(Text texts) {<br /><br /> List<;Text.TextBlock>; blocks = texts.getTextBlocks();<br /> if (blocks.size() == 0) {<br /> Toast.makeText(getApplicationContext(), "No text found", Toast.LENGTH_SHORT).show();<br /> return;<br /> }<br /> mGraphicOverlay.clear();<br /> for (Text.TextBlock block : texts.getTextBlocks()) {<br /> for (Text.Line line : block.getLines()) {<br /> for (Text.Element element : line.getElements()) {<br /><strong><span style="color: #008000;"> //Draws the bounding box around the element.</span></strong><br /> GraphicOverlay.Graphic textGraphic = new TextGraphic(mGraphicOverlay, element);<br /> mGraphicOverlay.add(textGraphic);<br /> }<br /> }<br /> }<br /> }<br /><br /><span style="color: #008000;"><strong> //get bitmap of image from app assets.</strong></span><br /> public Bitmap getBitmapFromAsset(Context context, String filePath) {<br /> AssetManager assetManager = context.getAssets();<br /><br /> InputStream is;<br /> Bitmap bitmap = null;<br /> try {<br /> is = assetManager.open(filePath);<br /> bitmap = BitmapFactory.decodeStream(is);<br /> } catch (IOException e) {<br /> e.printStackTrace();<br /> }<br /> return bitmap;<br /> }<br />}</pre> 
</div> 
 
 
 
<p>When you run the app it will look like this as shown below:</p> 
<p><img class="alignnone wp-image-2984" src="https://c1ctech.com/wp-content/uploads/2021/12/Screenshot_20211204-205741_TextRecognitionExp-498x1024.jpg" alt="" width="261" height="537" /> <img class="alignnone wp-image-2985" src="https://c1ctech.com/wp-content/uploads/2021/12/Screenshot_20211204-205752_TextRecognitionExp-498x1024.jpg" alt="" width="261" height="537" />

