react-native-text-reader 1.5.0 → 2.0.1
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.
- package/README.md +71 -48
- package/android/gradle.properties +4 -4
- package/android/src/main/java/com/textreader/TextReaderModule.kt +195 -109
- package/app.plugin.js +15 -0
- package/ios/TextReader.mm +6 -0
- package/ios/TextReader.swift +195 -35
- package/lib/commonjs/NativeTextReader.js +9 -0
- package/lib/commonjs/NativeTextReader.js.map +1 -0
- package/lib/commonjs/index.js +35 -12
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/package.json +1 -0
- package/lib/module/NativeTextReader.js +5 -0
- package/lib/module/NativeTextReader.js.map +1 -0
- package/lib/module/index.js +32 -13
- package/lib/module/index.js.map +1 -1
- package/lib/module/package.json +1 -0
- package/lib/typescript/commonjs/src/NativeTextReader.d.ts +34 -0
- package/lib/typescript/commonjs/src/NativeTextReader.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +27 -2
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/NativeTextReader.d.ts +34 -0
- package/lib/typescript/module/src/NativeTextReader.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +27 -2
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/package.json +73 -43
- package/react-native.config.json +1 -0
- package/src/NativeTextReader.ts +41 -0
- package/src/index.tsx +72 -18
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-text-reader",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A React Native library for OCR
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "A React Native library for OCR using Vision Framework on iOS and ML Kit on Android. Supports Expo development builds, detailed OCR metadata, and Android 16KB page size compatibility.",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
7
7
|
"module": "./lib/module/index.js",
|
|
@@ -15,7 +15,11 @@
|
|
|
15
15
|
"types": "./lib/typescript/commonjs/src/index.d.ts",
|
|
16
16
|
"default": "./lib/commonjs/index.js"
|
|
17
17
|
}
|
|
18
|
-
}
|
|
18
|
+
},
|
|
19
|
+
"./app.plugin.js": "./app.plugin.js"
|
|
20
|
+
},
|
|
21
|
+
"expo": {
|
|
22
|
+
"plugins": "./app.plugin.js"
|
|
19
23
|
},
|
|
20
24
|
"files": [
|
|
21
25
|
"src",
|
|
@@ -25,6 +29,7 @@
|
|
|
25
29
|
"cpp",
|
|
26
30
|
"*.podspec",
|
|
27
31
|
"react-native.config.json",
|
|
32
|
+
"app.plugin.js",
|
|
28
33
|
"!ios/build",
|
|
29
34
|
"!android/build",
|
|
30
35
|
"!android/gradle",
|
|
@@ -37,13 +42,17 @@
|
|
|
37
42
|
"!**/.*"
|
|
38
43
|
],
|
|
39
44
|
"scripts": {
|
|
40
|
-
"example": "
|
|
45
|
+
"example": "pnpm --filter react-native-text-reader-example",
|
|
46
|
+
"example:prebuild": "pnpm --filter react-native-text-reader-example prebuild",
|
|
47
|
+
"example:ios": "pnpm --filter react-native-text-reader-example ios",
|
|
48
|
+
"example:android": "pnpm --filter react-native-text-reader-example android",
|
|
41
49
|
"test": "jest",
|
|
42
50
|
"typecheck": "tsc",
|
|
43
51
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
44
52
|
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
45
53
|
"prepare": "bob build",
|
|
46
|
-
"release": "release-it"
|
|
54
|
+
"release": "release-it",
|
|
55
|
+
"audit": "pnpm audit --audit-level high"
|
|
47
56
|
},
|
|
48
57
|
"keywords": [
|
|
49
58
|
"react-native",
|
|
@@ -64,49 +73,59 @@
|
|
|
64
73
|
"registry": "https://registry.npmjs.org/"
|
|
65
74
|
},
|
|
66
75
|
"devDependencies": {
|
|
67
|
-
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
68
76
|
"@babel/plugin-transform-class-properties": "^7.27.1",
|
|
69
77
|
"@babel/preset-env": "^7.28.3",
|
|
70
|
-
"@commitlint/config-conventional": "^
|
|
71
|
-
"@evilmartians/lefthook": "^1.
|
|
72
|
-
"@react-native/eslint-config": "^0.
|
|
73
|
-
"@release-it/conventional-changelog": "^
|
|
74
|
-
"@types/jest": "^
|
|
75
|
-
"@types/react": "^19.
|
|
76
|
-
"commitlint": "^
|
|
77
|
-
"del-cli": "^
|
|
78
|
-
"eslint": "^8.
|
|
79
|
-
"eslint-config-prettier": "^
|
|
80
|
-
"eslint-plugin-prettier": "^5.
|
|
81
|
-
"jest": "^
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"react
|
|
85
|
-
"react-native
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
|
|
90
|
-
"resolutions": {
|
|
91
|
-
"@types/react": "^19.0.0"
|
|
78
|
+
"@commitlint/config-conventional": "^21.0.2",
|
|
79
|
+
"@evilmartians/lefthook": "^2.1.9",
|
|
80
|
+
"@react-native/eslint-config": "^0.86.0",
|
|
81
|
+
"@release-it/conventional-changelog": "^11.0.1",
|
|
82
|
+
"@types/jest": "^30.0.0",
|
|
83
|
+
"@types/react": "^19.2.17",
|
|
84
|
+
"commitlint": "^21.0.2",
|
|
85
|
+
"del-cli": "^7.0.0",
|
|
86
|
+
"eslint": "^8.57.1",
|
|
87
|
+
"eslint-config-prettier": "^10.1.8",
|
|
88
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
89
|
+
"jest": "^30.4.2",
|
|
90
|
+
"ts-jest": "^29.4.11",
|
|
91
|
+
"prettier": "^3.8.4",
|
|
92
|
+
"react": "19.2.7",
|
|
93
|
+
"react-native": "0.86.0",
|
|
94
|
+
"react-native-builder-bob": "^0.43.0",
|
|
95
|
+
"release-it": "^20.2.0",
|
|
96
|
+
"turbo": "^2.9.18",
|
|
97
|
+
"typescript": "^5.9.3"
|
|
92
98
|
},
|
|
93
99
|
"peerDependencies": {
|
|
94
100
|
"react": "*",
|
|
95
101
|
"react-native": "*"
|
|
96
102
|
},
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
|
|
100
|
-
|
|
103
|
+
"engines": {
|
|
104
|
+
"node": ">=22",
|
|
105
|
+
"pnpm": ">=11"
|
|
106
|
+
},
|
|
107
|
+
"packageManager": "pnpm@11.8.0",
|
|
101
108
|
"jest": {
|
|
102
|
-
"preset": "
|
|
109
|
+
"preset": "ts-jest",
|
|
110
|
+
"testEnvironment": "node",
|
|
103
111
|
"modulePathIgnorePatterns": [
|
|
104
|
-
"<rootDir>/
|
|
105
|
-
"<rootDir>/
|
|
112
|
+
"<rootDir>/lib/",
|
|
113
|
+
"<rootDir>/example/"
|
|
106
114
|
],
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
]
|
|
115
|
+
"setupFilesAfterEnv": [
|
|
116
|
+
"<rootDir>/jest.setup.js"
|
|
117
|
+
],
|
|
118
|
+
"moduleNameMapper": {
|
|
119
|
+
"^react-native$": "<rootDir>/jest.react-native-mock.js"
|
|
120
|
+
},
|
|
121
|
+
"transform": {
|
|
122
|
+
"^.+\\.tsx?$": [
|
|
123
|
+
"ts-jest",
|
|
124
|
+
{
|
|
125
|
+
"tsconfig": "tsconfig.test.json"
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
}
|
|
110
129
|
},
|
|
111
130
|
"commitlint": {
|
|
112
131
|
"extends": [
|
|
@@ -126,7 +145,7 @@
|
|
|
126
145
|
},
|
|
127
146
|
"plugins": {
|
|
128
147
|
"@release-it/conventional-changelog": {
|
|
129
|
-
"preset": "
|
|
148
|
+
"preset": "conventionalcommits"
|
|
130
149
|
}
|
|
131
150
|
}
|
|
132
151
|
},
|
|
@@ -136,6 +155,9 @@
|
|
|
136
155
|
"@react-native",
|
|
137
156
|
"prettier"
|
|
138
157
|
],
|
|
158
|
+
"plugins": [
|
|
159
|
+
"prettier"
|
|
160
|
+
],
|
|
139
161
|
"rules": {
|
|
140
162
|
"react/react-in-jsx-scope": "off",
|
|
141
163
|
"prettier/prettier": [
|
|
@@ -152,7 +174,8 @@
|
|
|
152
174
|
},
|
|
153
175
|
"eslintIgnore": [
|
|
154
176
|
"node_modules/",
|
|
155
|
-
"lib/"
|
|
177
|
+
"lib/",
|
|
178
|
+
"example/"
|
|
156
179
|
],
|
|
157
180
|
"prettier": {
|
|
158
181
|
"quoteProps": "consistent",
|
|
@@ -180,8 +203,7 @@
|
|
|
180
203
|
[
|
|
181
204
|
"typescript",
|
|
182
205
|
{
|
|
183
|
-
"project": "tsconfig.build.json"
|
|
184
|
-
"esm": true
|
|
206
|
+
"project": "tsconfig.build.json"
|
|
185
207
|
}
|
|
186
208
|
]
|
|
187
209
|
]
|
|
@@ -190,5 +212,13 @@
|
|
|
190
212
|
"type": "module-legacy",
|
|
191
213
|
"languages": "kotlin-swift",
|
|
192
214
|
"version": "0.42.0"
|
|
215
|
+
},
|
|
216
|
+
"codegenConfig": {
|
|
217
|
+
"name": "NativeTextReaderSpec",
|
|
218
|
+
"type": "modules",
|
|
219
|
+
"jsSrcsDir": "src",
|
|
220
|
+
"android": {
|
|
221
|
+
"javaPackageName": "com.textreader"
|
|
222
|
+
}
|
|
193
223
|
}
|
|
194
|
-
}
|
|
224
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export type NativeOptions = {
|
|
5
|
+
visionIgnoreThreshold?: number;
|
|
6
|
+
confidenceThreshold?: number;
|
|
7
|
+
script?: string;
|
|
8
|
+
recognitionLevel?: 'fast' | 'accurate';
|
|
9
|
+
recognitionLanguages?: string[];
|
|
10
|
+
customWords?: string[];
|
|
11
|
+
useLanguageCorrection?: boolean;
|
|
12
|
+
minimumTextHeight?: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type NativeTextLine = {
|
|
16
|
+
text: string;
|
|
17
|
+
confidence?: number;
|
|
18
|
+
frame?: {
|
|
19
|
+
top: number;
|
|
20
|
+
left: number;
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
};
|
|
24
|
+
recognizedLanguages?: string[];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type NativeDetailedResult = {
|
|
28
|
+
fullText: string;
|
|
29
|
+
lines: string[];
|
|
30
|
+
details: NativeTextLine[];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export interface Spec extends TurboModule {
|
|
34
|
+
read(imagePath: string, options?: NativeOptions): Promise<string[]>;
|
|
35
|
+
readDetailed(
|
|
36
|
+
imagePath: string,
|
|
37
|
+
options?: NativeOptions
|
|
38
|
+
): Promise<NativeDetailedResult>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default TurboModuleRegistry.get<Spec>('TextReader');
|
package/src/index.tsx
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { NativeModules, Platform } from 'react-native';
|
|
2
|
+
import NativeTextReaderModule from './NativeTextReader';
|
|
2
3
|
|
|
3
4
|
const LINKING_ERROR =
|
|
4
5
|
`The package 'react-native-text-reader' doesn't seem to be linked. Make sure: \n\n` +
|
|
5
6
|
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
|
|
6
7
|
'- You rebuilt the app after installing the package\n' +
|
|
7
|
-
'- You are not using Expo Go\n';
|
|
8
|
+
'- You are not using Expo Go (use a development build instead)\n';
|
|
8
9
|
|
|
9
|
-
const
|
|
10
|
-
|
|
10
|
+
const TextReaderModule = NativeTextReaderModule ?? NativeModules.TextReader;
|
|
11
|
+
|
|
12
|
+
const TextReader = TextReaderModule
|
|
13
|
+
? TextReaderModule
|
|
11
14
|
: new Proxy(
|
|
12
15
|
{},
|
|
13
16
|
{
|
|
@@ -25,30 +28,81 @@ export enum ScriptOptions {
|
|
|
25
28
|
KOREAN = 'Korean',
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
export type RecognitionLevel = 'fast' | 'accurate';
|
|
32
|
+
|
|
33
|
+
export type TextFrame = {
|
|
34
|
+
top: number;
|
|
35
|
+
left: number;
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type TextLine = {
|
|
41
|
+
text: string;
|
|
42
|
+
confidence?: number;
|
|
43
|
+
frame?: TextFrame;
|
|
44
|
+
recognizedLanguages?: string[];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type DetailedResult = {
|
|
48
|
+
fullText: string;
|
|
49
|
+
lines: string[];
|
|
50
|
+
details: TextLine[];
|
|
51
|
+
};
|
|
52
|
+
|
|
29
53
|
export type Options = {
|
|
30
|
-
visionIgnoreThreshold?: number;
|
|
31
|
-
|
|
54
|
+
visionIgnoreThreshold?: number;
|
|
55
|
+
confidenceThreshold?: number;
|
|
56
|
+
script?: ScriptOptions;
|
|
57
|
+
recognitionLevel?: RecognitionLevel;
|
|
58
|
+
recognitionLanguages?: string[];
|
|
59
|
+
customWords?: string[];
|
|
60
|
+
useLanguageCorrection?: boolean;
|
|
61
|
+
minimumTextHeight?: number;
|
|
32
62
|
};
|
|
33
63
|
|
|
34
|
-
type
|
|
64
|
+
type TextReaderNative = {
|
|
35
65
|
read(imagePath: string, options?: Options): Promise<string[]>;
|
|
66
|
+
readDetailed(imagePath: string, options?: Options): Promise<DetailedResult>;
|
|
36
67
|
};
|
|
37
68
|
|
|
69
|
+
const DEFAULT_OPTIONS: Options = {
|
|
70
|
+
script: ScriptOptions.LATIN,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
function normalizeDetailedResult(result: DetailedResult): DetailedResult {
|
|
74
|
+
return {
|
|
75
|
+
fullText: result.fullText ?? '',
|
|
76
|
+
lines: result.lines ?? [],
|
|
77
|
+
details: (result.details ?? []).map((detail) => ({
|
|
78
|
+
text: detail.text,
|
|
79
|
+
confidence: detail.confidence,
|
|
80
|
+
frame: detail.frame,
|
|
81
|
+
recognizedLanguages: detail.recognizedLanguages,
|
|
82
|
+
})),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Extracts text lines from an image.
|
|
88
|
+
*/
|
|
89
|
+
async function read(imagePath: string, options?: Options): Promise<string[]> {
|
|
90
|
+
const detailed = await readDetailed(imagePath, options);
|
|
91
|
+
return detailed.lines;
|
|
92
|
+
}
|
|
93
|
+
|
|
38
94
|
/**
|
|
39
|
-
* Extracts text
|
|
40
|
-
* @param imagePath - Image path
|
|
41
|
-
* @param options - Additional options
|
|
42
|
-
* @param options.visionIgnoreThreshold - Vision ignore threshold(iOS)
|
|
43
|
-
* @param options.script - Language script (Android)
|
|
95
|
+
* Extracts text with confidence, bounding boxes, and language metadata.
|
|
44
96
|
*/
|
|
45
|
-
async function
|
|
46
|
-
|
|
97
|
+
async function readDetailed(
|
|
98
|
+
imagePath: string,
|
|
99
|
+
options?: Options
|
|
100
|
+
): Promise<DetailedResult> {
|
|
101
|
+
const result = await TextReader.readDetailed(
|
|
47
102
|
imagePath,
|
|
48
|
-
options
|
|
49
|
-
script: ScriptOptions.LATIN,
|
|
50
|
-
}
|
|
103
|
+
options ?? DEFAULT_OPTIONS
|
|
51
104
|
);
|
|
105
|
+
return normalizeDetailedResult(result);
|
|
52
106
|
}
|
|
53
107
|
|
|
54
|
-
export default { read } as
|
|
108
|
+
export default { read, readDetailed } as TextReaderNative;
|