mediversal-rn-image-intelligence 1.0.7 β†’ 1.0.9

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 CHANGED
@@ -3,68 +3,130 @@
3
3
  [![npm version](https://badge.fury.io/js/mediversal-rn-image-intelligence.svg)](https://badge.fury.io/js/mediversal-rn-image-intelligence)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- 🎯 **Production-ready React Native library for intelligent image analysis using Google ML Kit (on-device)**
6
+ A production-ready React Native library for intelligent image analysis using Google ML Kit's on-device APIs. Analyze images to detect faces and extract text, with all processing happening locally on the device for maximum privacy and performance.
7
7
 
8
- Analyze images to detect faces, extract printed text, and recognize handwritten contentβ€”all processed locally on the device for maximum privacy and performance.
8
+ ## Overview
9
9
 
10
- ## 🌟 Features
10
+ This library provides a simple interface to Google ML Kit's powerful machine learning capabilities for mobile applications. You can detect human faces with detailed metadata including smile probability, eye state, and head rotation, as well as extract printed text from images with high accuracy using optical character recognition.
11
11
 
12
- - **Face Detection**: Detect human faces with detailed metadata (smiling probability, eye open probability, head rotation, etc.)
13
- - **Text Recognition (OCR)**: Extract printed text from images with high accuracy
14
- - **Handwriting Recognition**: Recognize handwritten text (requires stroke data)
15
- - **πŸš€ On-Device Processing**: All analysis happens locally using Google ML Kit
16
- - **πŸ”’ Privacy-First**: No data sent to external servers
17
- - **⚑ Fast & Efficient**: Optimized for mobile performance
18
- - **πŸ“± Cross-Platform**: Works seamlessly on iOS and Android
19
- - **🎨 TurboModule Architecture**: Built with React Native New Architecture support
20
- - **πŸ’ͺ TypeScript**: Fully typed API for excellent developer experience
12
+ Since all processing happens entirely on-device, your users' data never leaves their device. There's no need for an internet connection, no data is uploaded to external servers, and you get fast, reliable results even in offline scenarios.
21
13
 
22
- ## πŸ“¦ Installation
14
+ ## Key Features
15
+
16
+ **Face Detection**
17
+ Detect human faces in images with comprehensive metadata including smiling probability, eye open probability, and head rotation angles. Perfect for selfie validation, group photo analysis, and identity verification workflows.
18
+
19
+ **Text Recognition (OCR)**
20
+ Extract printed text from images with high accuracy. Ideal for document scanning, business card reading, receipt processing, and any scenario where you need to digitize text from photos.
21
+
22
+ **Privacy-First Architecture**
23
+ All image processing happens on-device using Google ML Kit. No images or extracted data are ever transmitted to external servers, ensuring complete privacy and GDPR compliance.
24
+
25
+ **Cross-Platform Support**
26
+ Works seamlessly on both iOS and Android with a unified API. Built with TurboModule specifications for the new React Native architecture.
27
+
28
+ **Performance Optimized**
29
+ Designed for mobile performance with efficient processing and the option to run face detection and text recognition in parallel.
30
+
31
+ **TypeScript Support**
32
+ Fully typed API provides excellent autocomplete and type safety in your development environment.
33
+
34
+ ## Installation
35
+
36
+ Install the package using npm:
23
37
 
24
38
  ```bash
25
39
  npm install mediversal-rn-image-intelligence
26
- # or
40
+ ```
41
+
42
+ Or if you prefer yarn:
43
+
44
+ ```bash
27
45
  yarn add mediversal-rn-image-intelligence
28
46
  ```
29
47
 
30
- ### iOS Setup
48
+ ## Platform-Specific Setup
49
+
50
+ ### iOS Configuration
51
+
52
+ After installing the package, you'll need to install the CocoaPods dependencies. Navigate to your iOS directory:
31
53
 
32
54
  ```bash
33
- cd ios && pod install
55
+ cd ios
56
+ pod install
57
+ cd ..
34
58
  ```
35
59
 
36
- **Required**: Add the following to your `Info.plist` if you need camera or photo library access:
60
+ Add the required permissions to your `ios/YourApp/Info.plist` file:
37
61
 
38
62
  ```xml
39
63
  <key>NSCameraUsageDescription</key>
40
- <string>We need access to your camera to capture images for analysis</string>
64
+ <string>We need camera access to capture and analyze images</string>
41
65
  <key>NSPhotoLibraryUsageDescription</key>
42
- <string>We need access to your photo library to analyze images</string>
66
+ <string>We need photo library access to select and analyze images</string>
43
67
  ```
44
68
 
45
- ### Android Setup
69
+ Requirements for iOS:
70
+
71
+ - iOS 12.0 or higher
72
+ - Xcode 12.0 or higher
73
+ - CocoaPods 1.10 or higher
46
74
 
47
- The library will automatically configure the required Google ML Kit dependencies. Ensure your `minSdkVersion` is at least 21:
75
+ ### Android Configuration
76
+
77
+ First, make sure your minimum SDK version is set to 21 or higher in `android/build.gradle`:
48
78
 
49
79
  ```gradle
50
- // android/build.gradle
51
80
  buildscript {
52
81
  ext {
53
82
  minSdkVersion = 21
83
+ compileSdkVersion = 33
84
+ targetSdkVersion = 33
54
85
  }
55
86
  }
56
87
  ```
57
88
 
58
- **Required**: Add permissions to your `AndroidManifest.xml` if needed:
89
+ Update your `android/app/build.gradle` to use Java 17:
90
+
91
+ ```gradle
92
+ android {
93
+ compileOptions {
94
+ sourceCompatibility JavaVersion.VERSION_17
95
+ targetCompatibility JavaVersion.VERSION_17
96
+ }
97
+
98
+ kotlinOptions {
99
+ jvmTarget = "17"
100
+ }
101
+ }
102
+ ```
103
+
104
+ Add the necessary permissions to `android/app/src/main/AndroidManifest.xml`:
59
105
 
60
106
  ```xml
61
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
62
107
  <uses-permission android:name="android.permission.CAMERA" />
108
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
109
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
63
110
  ```
64
111
 
65
- ## πŸš€ Usage
112
+ Remember to request these permissions at runtime in your application code:
66
113
 
67
- ### Basic Example
114
+ ```typescript
115
+ import { PermissionsAndroid, Platform } from 'react-native';
116
+
117
+ async function requestPermissions() {
118
+ if (Platform.OS === 'android') {
119
+ await PermissionsAndroid.requestMultiple([
120
+ PermissionsAndroid.PERMISSIONS.CAMERA,
121
+ PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
122
+ ]);
123
+ }
124
+ }
125
+ ```
126
+
127
+ ## Basic Usage
128
+
129
+ The simplest way to use the library is with the `analyzeImage` function. Pass it an image URI and it will return the analysis results:
68
130
 
69
131
  ```typescript
70
132
  import { analyzeImage } from 'mediversal-rn-image-intelligence';
@@ -74,21 +136,12 @@ async function analyzeMyImage() {
74
136
  const result = await analyzeImage('file:///path/to/image.jpg');
75
137
 
76
138
  console.log('Contains face:', result.containsFace);
77
- console.log('Contains printed text:', result.containsPrintedText);
78
- console.log('Contains handwritten text:', result.containsHandwrittenText);
139
+ console.log('Contains text:', result.containsPrintedText);
79
140
 
80
- // Access detected faces
81
141
  if (result.faces) {
82
- result.faces.forEach((face, index) => {
83
- console.log(`Face ${index + 1}:`);
84
- console.log(' Bounding box:', face.boundingBox);
85
- console.log(' Smiling:', face.smilingProbability);
86
- console.log(' Left eye open:', face.leftEyeOpenProbability);
87
- console.log(' Right eye open:', face.rightEyeOpenProbability);
88
- });
142
+ console.log('Number of faces:', result.faces.length);
89
143
  }
90
144
 
91
- // Access extracted text
92
145
  if (result.printedText) {
93
146
  console.log('Extracted text:', result.printedText);
94
147
  }
@@ -98,7 +151,9 @@ async function analyzeMyImage() {
98
151
  }
99
152
  ```
100
153
 
101
- ### Advanced Example with Options
154
+ ## Advanced Configuration
155
+
156
+ You can customize the analysis behavior by passing an options object:
102
157
 
103
158
  ```typescript
104
159
  import {
@@ -109,15 +164,32 @@ import {
109
164
  const options: AnalysisOptions = {
110
165
  detectFaces: true,
111
166
  detectPrintedText: true,
112
- detectHandwrittenText: false, // Skip handwriting for performance
113
- faceDetectionMode: 'accurate', // 'fast' or 'accurate'
114
- minFaceSize: 0.15, // Minimum face size (0.0 to 1.0)
167
+ faceDetectionMode: 'accurate',
168
+ minFaceSize: 0.15,
115
169
  };
116
170
 
117
171
  const result = await analyzeImage('file:///path/to/image.jpg', options);
118
172
  ```
119
173
 
120
- ### With Image Picker
174
+ ### Available Options
175
+
176
+ **detectFaces** (boolean, default: true)
177
+ Enable or disable face detection. Set to false if you only need text recognition to improve performance.
178
+
179
+ **detectPrintedText** (boolean, default: true)
180
+ Enable or disable text recognition. Set to false if you only need face detection to improve performance.
181
+
182
+ **faceDetectionMode** ('fast' | 'accurate', default: 'fast')
183
+ Choose between fast processing for real-time scenarios or accurate mode for higher quality detection. Use 'fast' for camera previews and 'accurate' for analyzing stored images.
184
+
185
+ **minFaceSize** (number, default: 0.1)
186
+ The minimum face size to detect, expressed as a proportion of the image's smaller dimension. Valid range is 0.0 to 1.0. Increase this value to filter out small or distant faces.
187
+
188
+ ## Integration with Image Picker
189
+
190
+ This library works seamlessly with React Native image picker libraries. Here are examples using react-native-image-picker:
191
+
192
+ ### Selecting from Gallery
121
193
 
122
194
  ```typescript
123
195
  import { launchImageLibrary } from 'react-native-image-picker';
@@ -136,11 +208,41 @@ async function pickAndAnalyze() {
136
208
  }
137
209
  ```
138
210
 
139
- ### React Component Example
211
+ ### Capturing with Camera
212
+
213
+ ```typescript
214
+ import { launchCamera } from 'react-native-image-picker';
215
+ import { analyzeImage } from 'mediversal-rn-image-intelligence';
216
+
217
+ async function captureAndAnalyze() {
218
+ const response = await launchCamera({
219
+ mediaType: 'photo',
220
+ quality: 1,
221
+ });
222
+
223
+ if (response.assets && response.assets[0].uri) {
224
+ const result = await analyzeImage(response.assets[0].uri);
225
+ console.log(result);
226
+ }
227
+ }
228
+ ```
229
+
230
+ ## Complete Example Component
231
+
232
+ Here's a full working example of a React component that lets users select an image and displays the analysis results:
140
233
 
141
234
  ```typescript
142
235
  import React, { useState } from 'react';
143
- import { View, Button, Text, Image } from 'react-native';
236
+ import {
237
+ View,
238
+ Button,
239
+ Text,
240
+ Image,
241
+ StyleSheet,
242
+ ScrollView,
243
+ ActivityIndicator,
244
+ Alert,
245
+ } from 'react-native';
144
246
  import { launchImageLibrary } from 'react-native-image-picker';
145
247
  import {
146
248
  analyzeImage,
@@ -153,7 +255,10 @@ export default function ImageAnalyzer() {
153
255
  const [loading, setLoading] = useState(false);
154
256
 
155
257
  const selectAndAnalyze = async () => {
156
- const response = await launchImageLibrary({ mediaType: 'photo' });
258
+ const response = await launchImageLibrary({
259
+ mediaType: 'photo',
260
+ quality: 1,
261
+ });
157
262
 
158
263
  if (response.assets && response.assets[0].uri) {
159
264
  const uri = response.assets[0].uri;
@@ -161,9 +266,14 @@ export default function ImageAnalyzer() {
161
266
  setLoading(true);
162
267
 
163
268
  try {
164
- const analysis = await analyzeImage(uri);
269
+ const analysis = await analyzeImage(uri, {
270
+ detectFaces: true,
271
+ detectPrintedText: true,
272
+ faceDetectionMode: 'accurate',
273
+ });
165
274
  setResult(analysis);
166
275
  } catch (error) {
276
+ Alert.alert('Error', 'Failed to analyze image');
167
277
  console.error(error);
168
278
  } finally {
169
279
  setLoading(false);
@@ -172,86 +282,269 @@ export default function ImageAnalyzer() {
172
282
  };
173
283
 
174
284
  return (
175
- <View style={{ padding: 20 }}>
285
+ <ScrollView contentContainerStyle={styles.container}>
286
+ <Text style={styles.title}>Image Intelligence Demo</Text>
287
+
176
288
  <Button title="Select Image" onPress={selectAndAnalyze} />
177
289
 
178
290
  {imageUri && (
179
- <Image source={{ uri: imageUri }} style={{ width: 300, height: 300 }} />
291
+ <Image
292
+ source={{ uri: imageUri }}
293
+ style={styles.image}
294
+ resizeMode="contain"
295
+ />
180
296
  )}
181
297
 
182
- {loading && <Text>Analyzing...</Text>}
298
+ {loading && (
299
+ <View style={styles.loadingContainer}>
300
+ <ActivityIndicator size="large" color="#007AFF" />
301
+ <Text style={styles.loadingText}>Analyzing...</Text>
302
+ </View>
303
+ )}
304
+
305
+ {result && !loading && (
306
+ <View style={styles.resultsContainer}>
307
+ <Text style={styles.resultTitle}>Results</Text>
308
+
309
+ <Text style={styles.resultItem}>
310
+ Face Detected: {result.containsFace ? 'Yes' : 'No'}
311
+ </Text>
183
312
 
184
- {result && (
185
- <View style={{ marginTop: 20 }}>
186
- <Text>Faces detected: {result.containsFace ? 'Yes' : 'No'}</Text>
187
- <Text>
188
- Text detected: {result.containsPrintedText ? 'Yes' : 'No'}
313
+ <Text style={styles.resultItem}>
314
+ Text Detected: {result.containsPrintedText ? 'Yes' : 'No'}
189
315
  </Text>
190
- {result.faces && <Text>Number of faces: {result.faces.length}</Text>}
316
+
317
+ {result.faces && result.faces.length > 0 && (
318
+ <View style={styles.section}>
319
+ <Text style={styles.sectionTitle}>
320
+ Faces Found: {result.faces.length}
321
+ </Text>
322
+ {result.faces.map((face, index) => (
323
+ <View key={index} style={styles.faceInfo}>
324
+ <Text>Face {index + 1}:</Text>
325
+ <Text>
326
+ Smiling: {(face.smilingProbability! * 100).toFixed(0)}%
327
+ </Text>
328
+ <Text>
329
+ Left Eye Open:{' '}
330
+ {(face.leftEyeOpenProbability! * 100).toFixed(0)}%
331
+ </Text>
332
+ <Text>
333
+ Right Eye Open:{' '}
334
+ {(face.rightEyeOpenProbability! * 100).toFixed(0)}%
335
+ </Text>
336
+ </View>
337
+ ))}
338
+ </View>
339
+ )}
340
+
191
341
  {result.printedText && (
192
- <Text>Extracted text: {result.printedText}</Text>
342
+ <View style={styles.section}>
343
+ <Text style={styles.sectionTitle}>Extracted Text:</Text>
344
+ <Text style={styles.extractedText}>{result.printedText}</Text>
345
+ </View>
346
+ )}
347
+
348
+ {result.errors && (
349
+ <View style={styles.errorSection}>
350
+ <Text style={styles.errorTitle}>Errors:</Text>
351
+ {result.errors.faceDetection && (
352
+ <Text style={styles.errorText}>
353
+ Face Detection: {result.errors.faceDetection}
354
+ </Text>
355
+ )}
356
+ {result.errors.textRecognition && (
357
+ <Text style={styles.errorText}>
358
+ Text Recognition: {result.errors.textRecognition}
359
+ </Text>
360
+ )}
361
+ </View>
193
362
  )}
194
363
  </View>
195
364
  )}
196
- </View>
365
+ </ScrollView>
197
366
  );
198
367
  }
368
+
369
+ const styles = StyleSheet.create({
370
+ container: {
371
+ padding: 20,
372
+ alignItems: 'center',
373
+ },
374
+ title: {
375
+ fontSize: 24,
376
+ fontWeight: 'bold',
377
+ marginBottom: 20,
378
+ },
379
+ image: {
380
+ width: 300,
381
+ height: 300,
382
+ marginVertical: 20,
383
+ },
384
+ loadingContainer: {
385
+ alignItems: 'center',
386
+ marginVertical: 20,
387
+ },
388
+ loadingText: {
389
+ marginTop: 10,
390
+ fontSize: 16,
391
+ },
392
+ resultsContainer: {
393
+ marginTop: 20,
394
+ padding: 15,
395
+ backgroundColor: '#f5f5f5',
396
+ borderRadius: 10,
397
+ width: '100%',
398
+ },
399
+ resultTitle: {
400
+ fontSize: 20,
401
+ fontWeight: 'bold',
402
+ marginBottom: 10,
403
+ },
404
+ resultItem: {
405
+ fontSize: 16,
406
+ marginVertical: 5,
407
+ },
408
+ section: {
409
+ marginTop: 15,
410
+ },
411
+ sectionTitle: {
412
+ fontSize: 16,
413
+ fontWeight: 'bold',
414
+ marginBottom: 8,
415
+ },
416
+ faceInfo: {
417
+ marginLeft: 10,
418
+ marginVertical: 5,
419
+ },
420
+ extractedText: {
421
+ fontSize: 14,
422
+ lineHeight: 20,
423
+ },
424
+ errorSection: {
425
+ marginTop: 15,
426
+ padding: 10,
427
+ backgroundColor: '#ffebee',
428
+ borderRadius: 5,
429
+ },
430
+ errorTitle: {
431
+ fontSize: 16,
432
+ fontWeight: 'bold',
433
+ color: '#c62828',
434
+ marginBottom: 5,
435
+ },
436
+ errorText: {
437
+ fontSize: 14,
438
+ color: '#d32f2f',
439
+ },
440
+ });
199
441
  ```
200
442
 
201
- ## πŸ“š API Reference
443
+ ## API Reference
444
+
445
+ ### analyzeImage()
202
446
 
203
- ### `analyzeImage(imageUri: string, options?: AnalysisOptions): Promise<AnalysisResult>`
447
+ ```typescript
448
+ analyzeImage(imageUri: string, options?: AnalysisOptions): Promise<AnalysisResult>
449
+ ```
204
450
 
205
- Main function to analyze an image.
451
+ Analyzes an image and returns the detection results.
206
452
 
207
453
  **Parameters:**
208
454
 
209
- - `imageUri` (string): Local file URI. Supported formats:
210
- - Android: `file:///path/to/image.jpg`, `content://...`, or absolute path
211
- - iOS: `file:///path/to/image.jpg`, `ph://...`, `assets-library://...`, or absolute path
212
- - `options` (AnalysisOptions, optional): Configuration options
455
+ **imageUri** (string, required)
456
+ The local file URI pointing to the image you want to analyze. Supported URI formats vary by platform:
213
457
 
214
- **Returns:** Promise<AnalysisResult>
458
+ - Android: file://, content://, or absolute filesystem paths
459
+ - iOS: file://, ph://, assets-library://, or absolute filesystem paths
215
460
 
216
- ### `isAvailable(): Promise<boolean>`
461
+ **options** (AnalysisOptions, optional)
462
+ Configuration object to customize the analysis behavior. See the Advanced Configuration section for available options.
217
463
 
218
- Check if the library is properly installed and native modules are available.
464
+ **Returns:**
465
+ A Promise that resolves to an AnalysisResult object containing the detection results.
219
466
 
220
- ## πŸ“‹ Types
467
+ **Throws:**
468
+ An error if the image URI is invalid or if both face detection and text recognition fail.
221
469
 
222
- ### `AnalysisResult`
470
+ ### isAvailable()
471
+
472
+ ```typescript
473
+ isAvailable(): Promise<boolean>
474
+ ```
475
+
476
+ Checks whether the native modules are properly linked and available for use.
477
+
478
+ **Returns:**
479
+ A Promise that resolves to true if the library is ready to use, false otherwise.
480
+
481
+ This is useful for verifying that the installation was successful before attempting to analyze images.
482
+
483
+ ## TypeScript Type Definitions
484
+
485
+ ### AnalysisResult
223
486
 
224
487
  ```typescript
225
488
  interface AnalysisResult {
226
489
  containsFace: boolean;
227
490
  containsPrintedText: boolean;
228
- containsHandwrittenText: boolean;
229
491
  faces?: FaceData[];
230
492
  printedText?: string;
231
- handwrittenText?: string;
232
493
  errors?: {
233
494
  faceDetection?: string;
234
495
  textRecognition?: string;
235
- handwritingRecognition?: string;
236
496
  };
237
497
  }
238
498
  ```
239
499
 
240
- ### `FaceData`
500
+ **containsFace**
501
+ Boolean indicating whether at least one face was detected in the image.
502
+
503
+ **containsPrintedText**
504
+ Boolean indicating whether any text was detected in the image.
505
+
506
+ **faces**
507
+ Optional array of FaceData objects, one for each detected face. Only present if faces were detected.
508
+
509
+ **printedText**
510
+ Optional string containing all the text extracted from the image. Only present if text was detected.
511
+
512
+ **errors**
513
+ Optional object containing error messages if either detection method encountered issues. This allows partial results - for example, face detection might succeed while text recognition fails.
514
+
515
+ ### FaceData
241
516
 
242
517
  ```typescript
243
518
  interface FaceData {
244
519
  boundingBox: BoundingBox;
245
- smilingProbability?: number; // 0.0 to 1.0
246
- leftEyeOpenProbability?: number; // 0.0 to 1.0
247
- rightEyeOpenProbability?: number; // 0.0 to 1.0
248
- headEulerAngleY?: number; // Yaw in degrees
249
- headEulerAngleZ?: number; // Roll in degrees
520
+ smilingProbability?: number;
521
+ leftEyeOpenProbability?: number;
522
+ rightEyeOpenProbability?: number;
523
+ headEulerAngleY?: number;
524
+ headEulerAngleZ?: number;
250
525
  trackingId?: number;
251
526
  }
252
527
  ```
253
528
 
254
- ### `BoundingBox`
529
+ **boundingBox**
530
+ The location and size of the detected face within the image.
531
+
532
+ **smilingProbability**
533
+ A number between 0.0 and 1.0 indicating the likelihood that the person is smiling. 0.0 means definitely not smiling, 1.0 means definitely smiling, and 0.5 indicates uncertainty.
534
+
535
+ **leftEyeOpenProbability** and **rightEyeOpenProbability**
536
+ Numbers between 0.0 and 1.0 indicating the likelihood that each eye is open.
537
+
538
+ **headEulerAngleY** (yaw)
539
+ The rotation of the head from left to right in degrees. A value of 0 means the face is looking straight at the camera, positive values mean the head is turned to the right, and negative values mean turned to the left.
540
+
541
+ **headEulerAngleZ** (roll)
542
+ The tilt of the head in degrees. A value of 0 means the head is upright, positive values mean tilted clockwise, and negative values mean tilted counter-clockwise.
543
+
544
+ **trackingId**
545
+ A unique identifier for the face, useful for tracking the same face across multiple frames in video scenarios.
546
+
547
+ ### BoundingBox
255
548
 
256
549
  ```typescript
257
550
  interface BoundingBox {
@@ -262,100 +555,208 @@ interface BoundingBox {
262
555
  }
263
556
  ```
264
557
 
265
- ### `AnalysisOptions`
558
+ Represents the rectangular region containing a detected face. The coordinate system has its origin (0, 0) at the top-left corner of the image, with x increasing to the right and y increasing downward. All values are in pixels.
559
+
560
+ ### AnalysisOptions
266
561
 
267
562
  ```typescript
268
563
  interface AnalysisOptions {
269
- detectFaces?: boolean; // default: true
270
- detectPrintedText?: boolean; // default: true
271
- detectHandwrittenText?: boolean; // default: true
272
- faceDetectionMode?: 'fast' | 'accurate'; // default: 'fast'
273
- minFaceSize?: number; // 0.0 to 1.0, default: 0.1
564
+ detectFaces?: boolean;
565
+ detectPrintedText?: boolean;
566
+ faceDetectionMode?: 'fast' | 'accurate';
567
+ minFaceSize?: number;
568
+ }
569
+ ```
570
+
571
+ All fields are optional and have sensible defaults. See the Advanced Configuration section for detailed descriptions.
572
+
573
+ ## Common Use Cases
574
+
575
+ ### Counting People in Group Photos
576
+
577
+ ```typescript
578
+ const result = await analyzeImage(photoUri, {
579
+ detectFaces: true,
580
+ detectPrintedText: false,
581
+ });
582
+
583
+ const faceCount = result.faces?.length || 0;
584
+ console.log(`Found ${faceCount} people in the photo`);
585
+ ```
586
+
587
+ ### Document Scanning and Text Extraction
588
+
589
+ ```typescript
590
+ const result = await analyzeImage(documentUri, {
591
+ detectFaces: false,
592
+ detectPrintedText: true,
593
+ });
594
+
595
+ if (result.printedText) {
596
+ await saveToDatabase(result.printedText);
274
597
  }
275
598
  ```
276
599
 
277
- ## ⚑ Performance Tips
600
+ ### Selfie Validation
601
+
602
+ ```typescript
603
+ const result = await analyzeImage(selfieUri, {
604
+ detectFaces: true,
605
+ minFaceSize: 0.3,
606
+ faceDetectionMode: 'accurate',
607
+ });
608
+
609
+ const isValidSelfie =
610
+ result.faces?.length === 1 && result.faces[0].smilingProbability! > 0.5;
611
+ ```
612
+
613
+ ### ID Card and Document Verification
278
614
 
279
- 1. **Use 'fast' mode for real-time applications**: The `faceDetectionMode: 'fast'` option provides better performance for live camera feeds.
615
+ ```typescript
616
+ const result = await analyzeImage(idCardUri, {
617
+ detectFaces: true,
618
+ detectPrintedText: true,
619
+ faceDetectionMode: 'accurate',
620
+ });
280
621
 
281
- 2. **Disable unused features**: If you only need face detection, disable text recognition:
622
+ const hasRequiredElements = result.containsFace && result.containsPrintedText;
623
+ ```
282
624
 
283
- ```typescript
284
- analyzeImage(uri, {
285
- detectPrintedText: false,
286
- detectHandwrittenText: false,
287
- });
288
- ```
625
+ ## Performance Considerations
289
626
 
290
- 3. **Optimize image size**: Resize large images before analysis to improve processing time.
627
+ **Choose the Right Detection Mode**
628
+ Use 'fast' mode for real-time scenarios like camera previews where speed is more important than perfect accuracy. Use 'accurate' mode when analyzing stored images where quality matters more than speed.
291
629
 
292
- 4. **Parallel processing**: The library automatically runs all enabled analyses in parallel for maximum efficiency.
630
+ **Disable Unused Features**
631
+ If you only need face detection, set `detectPrintedText: false` to improve performance. Similarly, if you only need text recognition, disable face detection.
293
632
 
294
- ## πŸ”’ Privacy & Security
633
+ **Optimize Image Size**
634
+ Large images take longer to process. Consider resizing images before analysis if you're working with high-resolution photos. Libraries like react-native-image-resizer can help:
295
635
 
296
- All image processing happens **locally on the device** using Google ML Kit's on-device APIs. No image data is ever sent to external servers, ensuring:
636
+ ```typescript
637
+ import ImageResizer from 'react-native-image-resizer';
297
638
 
298
- - βœ… Complete user privacy
299
- - βœ… Offline functionality
300
- - βœ… Faster processing
301
- - βœ… No data usage costs
302
- - βœ… GDPR & CCPA compliance
639
+ const resized = await ImageResizer.createResizedImage(
640
+ uri,
641
+ 1024,
642
+ 1024,
643
+ 'JPEG',
644
+ 80
645
+ );
303
646
 
304
- ## πŸ› Troubleshooting
647
+ const result = await analyzeImage(resized.uri);
648
+ ```
305
649
 
306
- ### iOS: "Module not found"
650
+ **First Run Download**
651
+ The first time you use the library, Google ML Kit needs to download its models (approximately 10-15 MB). This only happens once per device, but the first analysis may take longer than subsequent ones.
307
652
 
308
- Make sure you've run `pod install`:
653
+ **Cache Results When Appropriate**
654
+ If you're analyzing the same image multiple times, consider caching the results instead of re-processing the image.
655
+
656
+ ## Troubleshooting
657
+
658
+ ### iOS Module Not Found
659
+
660
+ If you see "Module not found" errors on iOS, make sure you've installed the CocoaPods dependencies:
309
661
 
310
662
  ```bash
311
- cd ios && pod install
663
+ cd ios
664
+ pod install
665
+ cd ..
666
+ npx react-native run-ios
312
667
  ```
313
668
 
314
- ### Android: Gradle build errors
669
+ ### Android Gradle Build Errors
315
670
 
316
- Ensure your `minSdkVersion` is at least 21 and you're using Java 11:
671
+ For generic Gradle build errors, try cleaning the build:
672
+
673
+ ```bash
674
+ cd android
675
+ ./gradlew clean
676
+ cd ..
677
+ npx react-native run-android
678
+ ```
679
+
680
+ ### Java Version Compatibility Issues
681
+
682
+ If you encounter compilation errors related to Java compatibility, ensure your `android/app/build.gradle` specifies Java 17:
317
683
 
318
684
  ```gradle
319
685
  android {
320
686
  compileOptions {
321
- sourceCompatibility JavaVersion.VERSION_11
322
- targetCompatibility JavaVersion.VERSION_11
687
+ sourceCompatibility JavaVersion.VERSION_17
688
+ targetCompatibility JavaVersion.VERSION_17
689
+ }
690
+ kotlinOptions {
691
+ jvmTarget = "17"
323
692
  }
324
693
  }
325
694
  ```
326
695
 
327
- ### Image URI format errors
696
+ ### Permission Denied Errors
328
697
 
329
- - **Android**: Use `file://`, `content://`, or absolute paths
330
- - **iOS**: Use `file://`, `ph://`, `assets-library://`, or absolute paths
698
+ Remember that on Android, you need to request permissions at runtime, not just declare them in the manifest:
331
699
 
332
- ### Digital Ink Recognition limitation
700
+ ```typescript
701
+ import { PermissionsAndroid, Platform } from 'react-native';
702
+
703
+ if (Platform.OS === 'android') {
704
+ await PermissionsAndroid.request(
705
+ PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE
706
+ );
707
+ }
708
+ ```
709
+
710
+ ### Image URI Format Issues
711
+
712
+ Make sure you're using the correct URI format for your platform:
713
+
714
+ - Android accepts: file://, content://, or absolute paths
715
+ - iOS accepts: file://, ph://, assets-library://, or absolute paths
716
+
717
+ ## Privacy and Security
333
718
 
334
- The Digital Ink Recognition API is designed for real-time stroke data (from drawing apps), not static images. For handwriting recognition in static images, consider:
719
+ This library is designed with privacy as a core principle. All image processing happens entirely on-device using Google ML Kit. Your users' images and the data extracted from them never leave their device. No internet connection is required for the library to function, and no data is transmitted to external servers.
335
720
 
336
- - Using Google Cloud Vision API (cloud-based)
337
- - Pre-processing images to extract stroke information
338
- - Using alternative OCR solutions specifically designed for handwriting
721
+ This makes the library GDPR compliant by default, as user data stays under their control. The library doesn't collect any analytics or telemetry, and the source code is open for review to verify these privacy guarantees.
339
722
 
340
- ## 🀝 Contributing
723
+ ## Technical Details
341
724
 
342
- Contributions are welcome! Please feel free to submit a Pull Request.
725
+ The library includes the following Google ML Kit components:
343
726
 
344
- ## πŸ“„ License
727
+ - Face Detection (Android: version 16.1.5, iOS: version 4.0.0)
728
+ - Text Recognition v2 (Android: version 19.0.0, iOS: version 4.0.0)
345
729
 
346
- MIT Β© Mediversal
730
+ It's built with TurboModule specifications to be compatible with React Native's new architecture. The package includes full TypeScript type definitions and integrates with iOS via CocoaPods and Android via Gradle.
347
731
 
348
- ## πŸ™ Acknowledgments
732
+ ## Contributing
349
733
 
350
- Built with:
734
+ Contributions are welcome. Please read the CONTRIBUTING.md file in the repository for guidelines on how to submit issues and pull requests.
351
735
 
352
- - [Google ML Kit](https://developers.google.com/ml-kit)
353
- - [React Native](https://reactnative.dev/)
736
+ ## License
354
737
 
355
- ## πŸ“ž Support
738
+ This project is licensed under the MIT License. See the LICENSE file for complete terms.
356
739
 
357
- - πŸ“§ Email: sushantbibhu@gmail.com
358
- - πŸ› Issues: [GitHub Issues](https://github.com/thisissushant/mediversal-rn-image-intelligence)
359
- - πŸ“– Documentation: [GitHub Wiki](https://github.com/thisissushant/mediversal-rn-image-intelligence)
740
+ ## Author
741
+
742
+ Sushant Singh
743
+
744
+ Email: sushantbibhu@gmail.com
745
+
746
+ GitHub: @thisissushant
747
+
748
+ ## Support and Community
749
+
750
+ If you need help or want to discuss the library:
751
+
752
+ - Report bugs or request features via GitHub Issues
753
+ - Join discussions on GitHub Discussions
754
+ - Contact the author directly at sushantbibhu@gmail.com
755
+
756
+ ## Acknowledgments
757
+
758
+ This library is built on top of Google ML Kit and React Native. Thanks to both teams for their excellent work that makes projects like this possible.
360
759
 
361
760
  ---
761
+
762
+ If this library has been helpful for your project, consider giving it a star on GitHub to help others discover it.