Skip to content

Commit 987caf9

Browse files
added image picker library to pick image from gallery to perform text recognition
1 parent 0fe9850 commit 987caf9

File tree

8 files changed

+117
-40
lines changed

8 files changed

+117
-40
lines changed

.idea/misc.xml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,8 @@ dependencies {
6767

6868
// Text features
6969
implementation "com.google.android.gms:play-services-mlkit-text-recognition:$mlKitVersion"
70+
71+
// gallery picker
72+
implementation 'com.github.dhaval2404:imagepicker:2.1'
73+
7074
}

app/src/main/java/com/example/textrecognizer/MainActivity.kt

Lines changed: 74 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.example.textrecognizer.databinding.ActivityMainBinding
88
import com.google.mlkit.vision.text.TextRecognition
99
import com.google.mlkit.vision.text.TextRecognizer
1010
import android.Manifest
11+
import android.app.Activity
1112
import android.content.ClipData
1213
import android.content.ClipboardManager
1314
import android.content.pm.PackageManager
@@ -22,24 +23,27 @@ import com.google.mlkit.vision.text.Text
2223
import java.util.concurrent.ExecutorService
2324
import java.util.concurrent.Executors
2425
import android.content.Intent
26+
import android.net.Uri
2527
import android.text.util.Linkify
2628
import android.view.Menu
2729
import android.view.MenuItem
28-
29-
const val PREVIEW_STATE = "PreviewState"
30-
const val IMAGE_STATE = "ImageState"
30+
import androidx.core.graphics.drawable.toBitmap
31+
import com.github.dhaval2404.imagepicker.ImagePicker
3132

3233
class MainActivity : AppCompatActivity() {
3334

3435
private lateinit var binding: ActivityMainBinding
3536
private lateinit var recognizer: TextRecognizer
3637
private val TAG = "Testing"
3738
private val SAVED_TEXT_TAG = "SavedText"
39+
40+
//private val SAVED_IMAGE_BITMAP = "SavedImage"
3841
private val REQUEST_CODE_PERMISSIONS = 10
3942
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
4043

4144
lateinit var camera: Camera
4245
var state = ""
46+
var savedBitmap: Bitmap? = null
4347

4448
private lateinit var cameraExecutor: ExecutorService
4549

@@ -49,12 +53,18 @@ class MainActivity : AppCompatActivity() {
4953

5054
if (savedInstanceState != null) {
5155
val savedText = savedInstanceState.getString(SAVED_TEXT_TAG)
52-
if (isTextValid(savedText)) {
53-
binding.scrollView.visibility = View.VISIBLE
54-
binding.textInImage.text = savedInstanceState.getString(SAVED_TEXT_TAG)
56+
binding.apply {
57+
if (isTextValid(savedText)) {
58+
scrollView.visibility = View.VISIBLE
59+
textInImage.text = savedInstanceState.getString(SAVED_TEXT_TAG)
60+
}
61+
if (savedBitmap != null) {
62+
previewImage.visibility = View.VISIBLE
63+
previewImage.setImageBitmap(savedBitmap)
64+
}
65+
//previewImage.setImageBitmap(savedInstanceState.getParcelable(SAVED_IMAGE_BITMAP))
5566
}
5667
}
57-
5868
init()
5969
setContentView(binding.root)
6070
}
@@ -76,7 +86,6 @@ class MainActivity : AppCompatActivity() {
7686
}
7787

7888
private fun requestPermissions() {
79-
Log.d("testing", "got here")
8089
ActivityCompat.requestPermissions(
8190
this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
8291
)
@@ -113,31 +122,52 @@ class MainActivity : AppCompatActivity() {
113122
}
114123
}
115124

116-
/*override fun onCreateOptionsMenu(menu: Menu?): Boolean {
125+
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
117126
menuInflater.inflate(R.menu.main_menu, menu)
118127
return true
119128
}
120129

121130
override fun onOptionsItemSelected(item: MenuItem): Boolean {
122-
if (item.itemId == R.id.input) {
123-
state = when (state) {
124-
PREVIEW_STATE -> {
125-
item.setIcon(R.drawable.ic_photo_camera)
126-
IMAGE_STATE
127-
}
128-
IMAGE_STATE -> {
129-
item.setIcon(R.drawable.ic_image)
130-
PREVIEW_STATE
131-
}
132-
else -> {
133-
item.setIcon(R.drawable.ic_photo_camera)
134-
IMAGE_STATE
135-
}
136-
}
131+
if (item.itemId == R.id.gallery) {
132+
binding.scrollView.visibility = View.GONE
133+
ImagePicker.with(this)
134+
.galleryOnly()
135+
.crop()
136+
.compress(1024)
137+
.maxResultSize(1080, 1080)
138+
.start()
139+
140+
return true
141+
} else if (item.itemId == R.id.refresh) {
142+
binding.previewImage.visibility = View.GONE
143+
savedBitmap = null
137144
return true
138145
}
139146
return super.onOptionsItemSelected(item)
140-
}*/
147+
}
148+
149+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
150+
super.onActivityResult(requestCode, resultCode, data)
151+
when (resultCode) {
152+
Activity.RESULT_OK -> {
153+
//Image Uri will not be null for RESULT_OK
154+
val uri: Uri = data?.data!!
155+
156+
// Use Uri object instead of File to avoid storage permissions
157+
binding.previewImage.apply {
158+
visibility = View.VISIBLE
159+
setImageURI(uri)
160+
}
161+
//runTextRecognition(binding.previewImage.drawable.toBitmap())
162+
}
163+
ImagePicker.RESULT_ERROR -> {
164+
showToast(ImagePicker.getError(data))
165+
}
166+
else -> {
167+
showToast("Task Cancelled")
168+
}
169+
}
170+
}
141171

142172
private fun runTextRecognition(bitmap: Bitmap) {
143173
val inputImage = InputImage.fromBitmap(bitmap, 0)
@@ -204,11 +234,21 @@ class MainActivity : AppCompatActivity() {
204234

205235
binding.apply {
206236
// Set up the listener for take photo button
207-
cameraCaptureButton.setOnClickListener {
208-
if (viewFinder.bitmap != null) {
209-
runTextRecognition(viewFinder.bitmap!!)
210-
} else {
211-
showToast(getString(R.string.camera_error_default_msg))
237+
extractTextButton.setOnClickListener {
238+
when {
239+
previewImage.visibility == View.VISIBLE -> {
240+
savedBitmap = previewImage.drawable.toBitmap()
241+
runTextRecognition(savedBitmap!!)
242+
}
243+
viewFinder.bitmap != null -> {
244+
previewImage.visibility = View.VISIBLE
245+
savedBitmap = viewFinder.bitmap
246+
previewImage.setImageBitmap(viewFinder.bitmap!!)
247+
runTextRecognition(savedBitmap!!)
248+
}
249+
else -> {
250+
showToast(getString(R.string.camera_error_default_msg))
251+
}
212252
}
213253
}
214254

@@ -299,10 +339,14 @@ class MainActivity : AppCompatActivity() {
299339

300340
override fun onSaveInstanceState(outState: Bundle) {
301341
super.onSaveInstanceState(outState)
342+
outState.clear()
302343
val textInImage = (binding.textInImage.text).toString()
303344
if (isTextValid(textInImage)) {
304345
outState.putString(SAVED_TEXT_TAG, textInImage)
305346
}
347+
/*if (binding.previewImage.visibility == View.VISIBLE) {
348+
outState.putParcelable(SAVED_IMAGE_BITMAP, binding.previewImage.drawable.toBitmap())
349+
}*/
306350
}
307351

308352
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24"
6+
android:tint="?attr/colorControlNormal">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M12,6v3l4,-4 -4,-4v3c-4.42,0 -8,3.58 -8,8 0,1.57 0.46,3.03 1.24,4.26L6.7,14.8c-0.45,-0.83 -0.7,-1.79 -0.7,-2.8 0,-3.31 2.69,-6 6,-6zM18.76,7.74L17.3,9.2c0.44,0.84 0.7,1.79 0.7,2.8 0,3.31 -2.69,6 -6,6v-3l-4,4 4,4v-3c4.42,0 8,-3.58 8,-8 0,-1.57 -0.46,-3.03 -1.24,-4.26z"/>
10+
</vector>

app/src/main/res/layout/activity_main.xml

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
app:layout_constraintStart_toStartOf="parent"
1717
app:layout_constraintTop_toTopOf="parent" />
1818

19+
<ImageView
20+
android:id="@+id/previewImage"
21+
android:layout_width="match_parent"
22+
android:layout_height="match_parent"
23+
android:background="?attr/colorOnPrimary"
24+
android:visibility="gone" />
25+
1926
<ScrollView
2027
android:id="@+id/scrollView"
2128
android:layout_width="0dp"
@@ -24,7 +31,7 @@
2431
android:background="@drawable/gradient"
2532
android:elevation="2dp"
2633
android:visibility="gone"
27-
app:layout_constraintBottom_toTopOf="@id/cameraCaptureButton"
34+
app:layout_constraintBottom_toTopOf="@id/extractTextButton"
2835
app:layout_constraintLeft_toLeftOf="parent"
2936
app:layout_constraintRight_toRightOf="parent"
3037
app:layout_constraintTop_toTopOf="parent"
@@ -85,11 +92,11 @@
8592
android:layout_height="0dp"
8693
android:layout_marginStart="50dp"
8794
android:elevation="2dp"
95+
app:cardBackgroundColor="@color/purple_200"
8896
app:cardCornerRadius="10dp"
89-
app:layout_constraintBottom_toBottomOf="@id/cameraCaptureButton"
97+
app:layout_constraintBottom_toBottomOf="@id/extractTextButton"
9098
app:layout_constraintStart_toStartOf="parent"
91-
app:cardBackgroundColor="@color/purple_200"
92-
app:layout_constraintTop_toTopOf="@id/cameraCaptureButton">
99+
app:layout_constraintTop_toTopOf="@id/extractTextButton">
93100

94101
<ImageView
95102
android:id="@+id/torchImage"
@@ -101,7 +108,7 @@
101108
</com.google.android.material.card.MaterialCardView>
102109

103110
<Button
104-
android:id="@+id/cameraCaptureButton"
111+
android:id="@+id/extractTextButton"
105112
android:layout_width="wrap_content"
106113
android:layout_height="wrap_content"
107114
android:layout_marginBottom="50dp"
@@ -119,11 +126,11 @@
119126
android:layout_height="0dp"
120127
android:layout_marginEnd="50dp"
121128
android:elevation="2dp"
122-
app:cardCornerRadius="10dp"
123129
app:cardBackgroundColor="@color/purple_200"
124-
app:layout_constraintBottom_toBottomOf="@id/cameraCaptureButton"
130+
app:cardCornerRadius="10dp"
131+
app:layout_constraintBottom_toBottomOf="@id/extractTextButton"
125132
app:layout_constraintEnd_toEndOf="parent"
126-
app:layout_constraintTop_toTopOf="@id/cameraCaptureButton">
133+
app:layout_constraintTop_toTopOf="@id/extractTextButton">
127134

128135
<ImageView
129136
android:layout_width="match_parent"
@@ -153,6 +160,6 @@
153160
android:id="@+id/group"
154161
android:layout_width="wrap_content"
155162
android:layout_height="wrap_content"
156-
app:constraint_referenced_ids="torchButton,share,cameraCaptureButton" />
163+
app:constraint_referenced_ids="torchButton,share,extractTextButton" />
157164

158165
</androidx.constraintlayout.widget.ConstraintLayout>

app/src/main/res/menu/main_menu.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
xmlns:app="http://schemas.android.com/apk/res-auto">
44

55
<item
6-
android:id="@+id/input"
6+
android:id="@+id/refresh"
7+
android:icon="@drawable/ic_refresh"
8+
android:title="Refresh"
9+
app:showAsAction="always" />
10+
11+
<item
12+
android:id="@+id/gallery"
713
android:icon="@drawable/ic_image"
814
android:title="Input"
915
app:showAsAction="always" />

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ buildscript {
44
google()
55
mavenCentral()
66
maven { url rootProject.projectDir.getAbsolutePath() + '/libraries' }
7+
maven { url "https://jitpack.io" }
78
}
89
dependencies {
910
classpath "com.android.tools.build:gradle:7.0.2"

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ dependencyResolutionManagement {
44
google()
55
mavenCentral()
66
maven { url rootProject.projectDir.getAbsolutePath() + '/libraries' }
7+
maven { url "https://jitpack.io" }
78
}
89
}
910
rootProject.name = "Text Recognizer"

0 commit comments

Comments
 (0)