react-native-text-reader 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -95,5 +95,16 @@ dependencies {
95
95
  //noinspection GradleDynamicVersion
96
96
  implementation "com.facebook.react:react-native:+"
97
97
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
98
+
99
+ // To recognize Latin script
100
+ implementation 'com.google.mlkit:text-recognition:16.0.0'
101
+ // To recognize Chinese script
102
+ implementation 'com.google.mlkit:text-recognition-chinese:16.0.0'
103
+ // To recognize Devanagari script
104
+ implementation 'com.google.mlkit:text-recognition-devanagari:16.0.0'
105
+ // To recognize Japanese script
106
+ implementation 'com.google.mlkit:text-recognition-japanese:16.0.0'
107
+ // To recognize Korean script
108
+ implementation 'com.google.mlkit:text-recognition-korean:16.0.0'
98
109
  }
99
110
 
@@ -5,21 +5,152 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule
5
5
  import com.facebook.react.bridge.ReactMethod
6
6
  import com.facebook.react.bridge.Promise
7
7
 
8
+ import android.graphics.Point
9
+ import android.graphics.Rect
10
+ import android.net.Uri
11
+ import android.graphics.BitmapFactory
12
+ import android.graphics.Bitmap
13
+ import androidx.annotation.NonNull
14
+ import androidx.annotation.Nullable
15
+ import com.facebook.react.bridge.*
16
+ import com.google.android.gms.tasks.OnFailureListener
17
+ import com.google.android.gms.tasks.OnSuccessListener
18
+ import com.google.mlkit.vision.common.InputImage
19
+ import com.google.mlkit.vision.text.Text
20
+ import com.google.mlkit.vision.text.TextRecognition
21
+ import com.google.mlkit.vision.text.TextRecognizer
22
+ import com.google.mlkit.vision.text.TextRecognizerOptionsInterface
23
+ import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
24
+ import com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions
25
+ import com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions
26
+ import com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions
27
+ import com.google.mlkit.vision.text.latin.TextRecognizerOptions
28
+ import java.io.IOException
29
+ import java.net.URL
30
+
31
+
8
32
  class TextReaderModule(reactContext: ReactApplicationContext) :
9
33
  ReactContextBaseJavaModule(reactContext) {
34
+ override fun getName(): String {
35
+ return NAME
36
+ }
37
+
38
+ @Throws(IOException::class)
39
+ private fun getInputImage(reactContext: ReactApplicationContext, url: String): InputImage {
40
+ return if (url.contains("http://") || url.contains("https://")) {
41
+ val urlInput = URL(url)
42
+ val image: Bitmap = BitmapFactory.decodeStream(urlInput.openConnection().getInputStream())
43
+ InputImage.fromBitmap(image, 0)
44
+ } else {
45
+ val uri = Uri.parse(url)
46
+ InputImage.fromFilePath(reactContext, uri)
47
+ }
48
+ }
49
+
50
+ private fun rectToMap(rect: Rect): WritableMap {
51
+ return Arguments.createMap().apply {
52
+ putInt("width", rect.width())
53
+ putInt("height", rect.height())
54
+ putInt("top", rect.top)
55
+ putInt("left", rect.left)
56
+ }
57
+ }
58
+
59
+ private fun cornerPointsToMap(points: Array<Point>): WritableArray {
60
+ return Arguments.createArray().apply {
61
+ points.forEach { point ->
62
+ pushMap(Arguments.createMap().apply {
63
+ putInt("x", point.x)
64
+ putInt("y", point.y)
65
+ })
66
+ }
67
+ }
68
+ }
69
+
70
+ private fun langToMap(lang: String): WritableArray {
71
+ return Arguments.createArray().apply {
72
+ pushMap(Arguments.createMap().apply {
73
+ putString("languageCode", lang)
74
+ })
75
+ }
76
+ }
77
+
78
+ private fun lineToMap(line: Text.Line): WritableMap {
79
+ return Arguments.createMap().apply {
80
+ putString("text", line.text)
81
+ line.boundingBox?.let { putMap("frame", rectToMap(it)) }
82
+ line.cornerPoints?.let { putArray("cornerPoints", cornerPointsToMap(it)) }
83
+ putArray("recognizedLanguages", langToMap(line.recognizedLanguage))
84
+
85
+ val elementsArray = Arguments.createArray()
86
+ line.elements.forEach { element ->
87
+ elementsArray.pushMap(Arguments.createMap().apply {
88
+ putString("text", element.text)
89
+ element.boundingBox?.let { putMap("frame", rectToMap(it)) }
90
+ element.cornerPoints?.let { putArray("cornerPoints", cornerPointsToMap(it)) }
91
+ })
92
+ }
93
+ putArray("elements", elementsArray)
94
+ }
95
+ }
96
+
97
+ private fun blockToMap(block: Text.TextBlock): WritableMap {
98
+ return Arguments.createMap().apply {
99
+ putString("text", block.text)
100
+ block.boundingBox?.let { putMap("frame", rectToMap(it)) }
101
+ block.cornerPoints?.let { putArray("cornerPoints", cornerPointsToMap(it)) }
102
+
103
+ val linesArray = Arguments.createArray()
104
+ block.lines.forEach { line ->
105
+ linesArray.pushMap(lineToMap(line))
106
+ }
107
+ putArray("lines", linesArray)
108
+ putArray("recognizedLanguages", langToMap(block.recognizedLanguage))
109
+ }
110
+ }
111
+
112
+ @NonNull
113
+ private fun getScriptTextRecognizerOptions(@Nullable script: String?): TextRecognizerOptionsInterface {
114
+ return when (script) {
115
+ "Chinese" -> ChineseTextRecognizerOptions.Builder().build()
116
+ "Devanagari" -> DevanagariTextRecognizerOptions.Builder().build()
117
+ "Japanese" -> JapaneseTextRecognizerOptions.Builder().build()
118
+ "Korean" -> KoreanTextRecognizerOptions.Builder().build()
119
+ else -> TextRecognizerOptions.DEFAULT_OPTIONS
120
+ }
121
+ }
122
+
123
+ @ReactMethod
124
+ fun read(url: String, script: String, promise: Promise) {
125
+ try {
126
+ val image = getInputImage(reactApplicationContext, url)
127
+ val options = getScriptTextRecognizerOptions(script)
128
+ val recognizer: TextRecognizer = TextRecognition.getClient(options)
129
+
130
+ recognizer.process(image)
131
+ .addOnSuccessListener { visionText ->
132
+ val result = Arguments.createMap()
133
+ result.putString("text", visionText.text)
134
+
135
+ val blocksArray = Arguments.createArray()
136
+ visionText.textBlocks.forEach { block ->
137
+ blocksArray.pushMap(blockToMap(block))
138
+ }
139
+ result.putArray("blocks", blocksArray)
140
+
141
+ promise.resolve(result)
142
+ }
143
+ .addOnFailureListener { e ->
144
+ e.printStackTrace()
145
+ promise.reject("Text recognition failed", e)
146
+ }
147
+ } catch (e: IOException) {
148
+ e.printStackTrace()
149
+ promise.reject("Text recognition failed", e)
150
+ }
151
+ }
10
152
 
11
- override fun getName(): String {
12
- return NAME
13
- }
14
-
15
- // Example method
16
- // See https://reactnative.dev/docs/native-modules-android
17
- @ReactMethod
18
- fun multiply(a: Double, b: Double, promise: Promise) {
19
- promise.resolve(a * b)
20
- }
21
-
22
- companion object {
23
- const val NAME = "TextReader"
24
- }
25
- }
153
+ companion object {
154
+ const val NAME = "TextReader"
155
+ }
156
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-text-reader",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "A React Native library for OCR (Optical Character Recognition) using Vision Framework on iOS and Firebase ML Kit on Android.",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/commonjs/index.js",