This content originally appeared on DEV Community and was authored by Dilmohit
Hey guys today in this article, we will be creating an application that will lets users click Pictures and then let them detect text in those Pictures. For this we will be using firebase MLkit. And we will be creating this project using Java Language.
- Create a new Project in android studio -
- Connect this Project with firebase - if you don't know how to connect an android project with firebase, its quite simple.
- first open firebase website.
- Login using google account
- After that click on a new project
- Add an name for your project
- And click on create a project
- Then at the dashboard click at android icon
- On the register app page add the package name of the application. You can find this package name in almost all the files
- After that download json file and add that file here
- Add these dependencies in build.gradle/module
implementation 'com.google.firebase:firebase-core:20.1.0'
implementation 'com.google.android.gms:play-services-mlkit-text-recognition:18.0.0'
- Add these Permissions in AndroidManifest file
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
- Add this below code in your activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_width="200dp"
android:layout_height="150dp"
android:layout_marginTop="106dp"
android:layout_marginBottom="96dp"
app:cardCornerRadius="30dp"
app:layout_constraintBottom_toTopOf="@+id/idTVHead"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/idIVLogo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:scaleType="centerCrop"
android:contentDescription="@string/scanner_image"
android:src="@drawable/scanimg" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="18dp"
app:layout_constraintBottom_toTopOf="@+id/idBTNCapture"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView">
<TextView
android:id="@+id/idTVHead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/idIVLogo"
android:layout_centerHorizontal="true"
android:gravity="center"
android:padding="15dp"
android:text="Welcome To Text Detector"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold" />
</androidx.cardview.widget.CardView>
<!--This button is used to go in Scanner Activity-->
<Button
android:id="@+id/idBTNCapture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/idTVHead"
android:layout_marginBottom="205dp"
android:background="@drawable/button_back"
android:text="Capture Image"
android:textAllCaps="false"
app:backgroundTint="@color/teal_700"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/idTVHead" />
</androidx.constraintlayout.widget.ConstraintLayout>
- Add this below code in your MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this will hide status bar in this activity
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
// Initialize Button
Button captureButton = findViewById(R.id.idBTNCapture);
// add onclicklistener on button
captureButton.setOnClickListener(v -> {
Intent intent = new Intent(MainActivity.this, ScannerActivity.class);
startActivity(intent);
});
}
}
- Create a new Activity, name it as Scanner Activity or whatever you like. Add the below code in activity_scanner.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ScannerActivity">
<!--This CardView Contains imageView is where clicked image will show up-->
<androidx.cardview.widget.CardView
android:id="@+id/cardView2"
android:layout_width="200dp"
android:layout_height="150dp"
android:layout_marginTop="50dp"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/idIVCaptureImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/scanner_image"
android:scaleType="centerCrop"
android:src="@drawable/scanimg" />
</androidx.cardview.widget.CardView>
<!--This CardView Contains text view that will show the results-->
<androidx.cardview.widget.CardView
android:id="@+id/cardView3"
android:layout_width="300dp"
android:layout_height="200dp"
android:layout_marginTop="30dp"
app:cardCornerRadius="18dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView2">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/idIvDetectedText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:padding="20dp"
android:text="Your Result Will Appear Here"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold" />
</ScrollView>
</androidx.cardview.widget.CardView>
<!--This button is use to click picture-->
<Button
android:id="@+id/idBTNSnap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/idIvDetectedText"
android:layout_marginStart="91dp"
android:layout_marginTop="82dp"
android:background="@drawable/button_back"
android:text="Snap"
android:textAllCaps="false"
app:backgroundTint="@color/teal_700"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView3" />
<!--This button is used to detect text from images-->
<Button
android:id="@+id/idBTNDetect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/idBTNSnap"
android:layout_marginTop="82dp"
android:layout_marginEnd="82dp"
android:background="@drawable/button_back"
android:text="Detect"
android:textAllCaps="false"
app:backgroundTint="@color/teal_700"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView3" />
</androidx.constraintlayout.widget.ConstraintLayout>
- Add this below code in ScannerActivity.java
public class ScannerActivity extends AppCompatActivity {
// Initialize variables
private ImageView captureIV;
private TextView resultTV;
private Bitmap imageBitmap;
static final int REQUEST_IMAGE_CAPTURE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this will hide status bar in this activity
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_scanner);
captureIV = findViewById(R.id.idIVCaptureImage);
resultTV = findViewById(R.id.idIvDetectedText);
Button snapBTN = findViewById(R.id.idBTNSnap);
Button detectBTN = findViewById(R.id.idBTNDetect);
// set onclicklistener
detectBTN.setOnClickListener(v -> {
if (captureIV.getDrawable()==null){
Toast.makeText(ScannerActivity.this, "Failed to fetch Image", Toast.LENGTH_SHORT).show();
}else {
detectText();
}
});
// set onclicklistener
snapBTN.setOnClickListener(v -> {
if (checkPermission()){
captureImage();
}else {
requestPermission();
}
});
}
// check Camera Permission
private boolean checkPermission(){
int camerpermission = ContextCompat.checkSelfPermission(getApplicationContext(), CAMERA);
return camerpermission == PackageManager.PERMISSION_GRANTED;
}
// Request Camera Permission
private void requestPermission(){
int PERMISSION_CODE = 200;
ActivityCompat.requestPermissions(this, new String[]{CAMERA}, PERMISSION_CODE);
}
// Open Camera
@SuppressLint("QueryPermissionsNeeded")
private void captureImage(){
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePicture.resolveActivity(getPackageManager())!=null){
startActivityForResult(takePicture,REQUEST_IMAGE_CAPTURE);
}
}
// Show toast on the user response on Permission Request
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length>0){
boolean cameraPermision = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (cameraPermision){
Toast.makeText(this, "Permissions Granted", Toast.LENGTH_SHORT).show();
captureImage();
}else {
Toast.makeText(this, "Permissions Denied", Toast.LENGTH_SHORT).show();
}
}
}
// After detecting data add that data to text view
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK){
Bundle extras = Objects.requireNonNull(data).getExtras();
imageBitmap = (Bitmap) extras.get("data");
captureIV.setImageBitmap(imageBitmap);
}
}
// Detect text in image
private void detectText(){
InputImage image = InputImage.fromBitmap(imageBitmap,0);
TextRecognizer recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS);
Task<Text> result = recognizer.process(image).addOnSuccessListener(text -> {
StringBuilder result1 = new StringBuilder();
for (Text.TextBlock block: text.getTextBlocks()){
String blockText = block.getText();
Point[] blockCornerPoint = block.getCornerPoints();
Rect blockFrame = block.getBoundingBox();
for (Text.Line line: block.getLines()){
String lineText = line.getText();
Point[] lineCornerPoint = line.getCornerPoints();
Rect linREct = line.getBoundingBox();
for (Text.Element element: line.getElements()){
String elementText = element.getText();
result1.append(elementText);
}
resultTV.setText(blockText);
}
}
}).addOnFailureListener(e -> Toast.makeText(ScannerActivity.this, "Fail To Detect Text"+e.getMessage(), Toast.LENGTH_SHORT).show());
}
}
Output -
Thats it guys. Let me know your thoughts in the comments. Here is the Complete Source Code for this project.
This content originally appeared on DEV Community and was authored by Dilmohit
Dilmohit | Sciencx (2022-03-23T04:40:17+00:00) Text Detector App – An Android Project. Retrieved from https://www.scien.cx/2022/03/23/text-detector-app-an-android-project/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.