Skip to content

Commit e703a4a

Browse files
Merge pull request #49 from Michaelvilleneuve/android
Add basic android support
2 parents 4cb4e6c + 838b4d6 commit e703a4a

File tree

265 files changed

+29941
-114
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

265 files changed

+29941
-114
lines changed

Example/android/.project

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>android</name>
4+
<comment>Project android created by Buildship.</comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
16+
</natures>
17+
</projectDescription>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
connection.project.dir=
2+
eclipse.preferences.version=1

README.md

Lines changed: 84 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
![Demo gif](https://raw.githubusercontent.com/Michaelvilleneuve/react-native-document-scanner/master/images/demo.gif)
22

3-
# React Native Document Scanner (iOS only)
4-
5-
**Check out the android branch if you need both platforms, should be released soon**
3+
# React Native Document Scanner
64

75
Live document detection library. Returns either a URI or a base64 encoded string of the captured image, allowing you to easily store it or use it as you wish !
86

97
Features :
10-
- Live detection
11-
- Perspective correction and crop of the image
12-
- Live camera filters (brightness, saturation, contrast)
13-
- Flash
14-
- Easy to use base64 image
158

16-
#### Can be easily plugged with [react-native-perspective-image-cropper](https://github.com/Michaelvilleneuve/react-native-perspective-image-cropper)
9+
- Live detection
10+
- Perspective correction and crop of the image
11+
- Live camera filters (brightness, saturation, contrast)
12+
- Flash
13+
- Easy to use base64 image
1714

15+
#### Can be easily plugged with [react-native-perspective-image-cropper](https://github.com/Michaelvilleneuve/react-native-perspective-image-cropper)
1816

19-
![Demo crop gif](https://camo.githubusercontent.com/0ac887deaa7263172a5fd2759dba3d692e98585a/68747470733a2f2f73332d65752d776573742d312e616d617a6f6e6177732e636f6d2f6d69636861656c76696c6c656e657576652f64656d6f2d63726f702e676966)
17+
![Demo crop gif](https://camo.githubusercontent.com/0ac887deaa7263172a5fd2759dba3d692e98585a/68747470733a2f2f73332d65752d776573742d312e616d617a6f6e6177732e636f6d2f6d69636861656c76696c6c656e657576652f64656d6f2d63726f702e676966)
2018

21-
## Getting started
19+
## Both Platform
2220

2321
Use version >=1.4.1 if you are using react-native 0.48+
2422

@@ -30,21 +28,50 @@ Edit the `info.plist` file in XCode and add the following permission : `NSCamera
3028

3129
Remember, this library uses your device camera, you can't run it on a simulator.
3230

33-
### With Cocoapods
31+
### iOS if you want to use Cocoapods instead of default linking
3432

3533
If you want to use Cocoapods insteads of `react-native link`, add the following to your Podfile
3634

3735
```
3836
pod 'RNPdfScanner', :path => '../node_modules/react-native-document-scanner/ios'
3937
```
4038

39+
### Android Only
40+
41+
If you do not have it already in your project, you must link openCV in your `settings.gradle` file
42+
43+
```java
44+
include ':openCVLibrary310'
45+
project(':openCVLibrary310').projectDir = new File(rootProject.projectDir,'../node_modules/react-native-document-scanner/android/openCVLibrary310')
46+
```
47+
48+
#### In android/app/src/main/AndroidManifest.xml
49+
50+
Change manifest header to avoid "Manifest merger error". After you add `xmlns:tools="http://schemas.android.com/tools"` should look like this:
51+
52+
```
53+
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.<yourAppName>" xmlns:tools="http://schemas.android.com/tools">
54+
```
55+
56+
Add `tools:replace="android:allowBackup"` in <application tag. It should look like this:
57+
58+
```
59+
<application tools:replace="android:allowBackup" android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:allowBackup="false" android:theme="@style/AppTheme">
60+
```
61+
62+
Add Camera permissions request:
63+
64+
```
65+
<uses-permission android:name="android.permission.CAMERA" />
66+
```
4167

4268
## Usage
69+
4370
```javascript
44-
import React,{ Component } from 'react';
45-
import { View, Image } from 'react-native';
71+
import React, { Component } from "react";
72+
import { View, Image } from "react-native";
4673

47-
import DocumentScanner from 'react-native-document-scanner';
74+
import DocumentScanner from "react-native-document-scanner";
4875

4976
class YourComponent extends Component {
5077
render() {
@@ -53,61 +80,72 @@ class YourComponent extends Component {
5380
<DocumentScanner
5481
useBase64
5582
saveInAppDocument={false}
56-
onPictureTaken={data => this.setState({
57-
image: data.croppedImage,
58-
initialImage: data.initialImage,
59-
rectangleCoordinates: data.rectangleCoordinates,
60-
})}
83+
onPictureTaken={data =>
84+
this.setState({
85+
image: data.croppedImage,
86+
initialImage: data.initialImage,
87+
rectangleCoordinates: data.rectangleCoordinates
88+
})
89+
}
6190
overlayColor="rgba(255,130,0, 0.7)"
6291
enableTorch={false}
6392
brightness={0.3}
6493
saturation={1}
6594
contrast={1.1}
6695
quality={0.5}
67-
onRectangleDetect={({ stableCounter, lastDetectionType }) => this.setState({ stableCounter, lastDetectionType })}
96+
onRectangleDetect={({ stableCounter, lastDetectionType }) =>
97+
this.setState({ stableCounter, lastDetectionType })
98+
}
6899
detectionCountBeforeCapture={5}
69100
detectionRefreshRateInMS={50}
101+
onPermissionsDenied={() => console.log("Permissions Denied")}
102+
/>
103+
<Image
104+
source={{ uri: `data:image/jpeg;base64,${this.state.image}` }}
105+
resizeMode="contain"
70106
/>
71-
<Image source={{ uri: `data:image/jpeg;base64,${this.state.image}`}} resizeMode="contain" />
72107
</View>
73108
);
74109
}
75110
}
76-
77111
```
78112

79113
## Properties
80114

81-
| Prop | Default | Type | Description |
82-
| :-------- |:----:| :--------:| :----------|
83-
| overlayColor | `none` | `string` | Color of the detected rectangle : rgba recommended |
84-
| detectionCountBeforeCapture | `5` | `integer` | Number of correct rectangle to detect before capture |
85-
| detectionRefreshRateInMS | `50` | `integer` | Time between two rectangle detection attempt |
86-
| enableTorch | `false` | `bool` | Allows to active or deactivate flash during document detection |
87-
| useFrontCam | `false` | `bool` | Allows you to switch between front and back camera |
88-
| brightness | `0` | `float` | Increase or decrease camera brightness. Normal as default. |
89-
| saturation | `1` | `float` | Increase or decrease camera saturation. Set `0` for black & white |
90-
| contrast | `1` | `float` | Increase or decrease camera contrast. Normal as default |
91-
| quality | `0.8` | `float` | Image compression. Reduces both image size and quality |
92-
| useBase64 | `false` | `bool` | If base64 representation should be passed instead of image uri's |
93-
| saveInAppDocument | `false` | `bool` | If should save in app document in case of not using base 64 |
94-
| captureMultiple | `false` | `bool` | Keeps the scanner on after a successful capture |
115+
| Prop | Platform | Default | Type | Description |
116+
| :-------------------------- | :------: | :-----: | :-------: | :---------------------------------------------------------------- |
117+
| overlayColor | Both | `none` | `string` | Color of the detected rectangle : rgba recommended |
118+
| detectionCountBeforeCapture | Both | `5` | `integer` | Number of correct rectangle to detect before capture |
119+
| detectionRefreshRateInMS | iOS | `50` | `integer` | Time between two rectangle detection attempt |
120+
| enableTorch | Both | `false` | `bool` | Allows to active or deactivate flash during document detection |
121+
| useFrontCam | iOS | `false` | `bool` | Allows you to switch between front and back camera |
122+
| brightness | iOS | `0` | `float` | Increase or decrease camera brightness. Normal as default. |
123+
| saturation | iOS | `1` | `float` | Increase or decrease camera saturation. Set `0` for black & white |
124+
| contrast | iOS | `1` | `float` | Increase or decrease camera contrast. Normal as default |
125+
| quality | iOS | `0.8` | `float` | Image compression. Reduces both image size and quality |
126+
| useBase64 | iOS | `false` | `bool` | If base64 representation should be passed instead of image uri's |
127+
| saveInAppDocument | iOS | `false` | `bool` | If should save in app document in case of not using base 64 |
128+
| captureMultiple | iOS | `false` | `bool` | Keeps the scanner on after a successful capture |
129+
| onPermissionsDenied | android | `null` | `func` | Function to call when the Android permissions are denied |
95130

96131
## Manual capture
97132

98133
- First get component ref
134+
99135
```javascript
100-
<DocumentScanner ref={(ref) => this.scanner = ref} />
136+
<DocumentScanner ref={ref => (this.scanner = ref)} />
101137
```
102138

103139
- Then call :
140+
104141
```javascript
105142
this.scanner.capture();
106143
```
107144

108-
## Each rectangle detection
145+
## Each rectangle detection (iOS only)
146+
109147
| Props | Params | Type | Description |
110-
|-------------------|----------------------------------------|----------|-------------|
148+
| ----------------- | -------------------------------------- | -------- | ----------- |
111149
| onRectangleDetect | `{ stableCounter, lastDetectionType }` | `object` | See below |
112150

113151
The returned object includes the following keys :
@@ -119,30 +157,22 @@ Number of correctly formated rectangle found (this number triggers capture once
119157
- `lastDetectionType`
120158

121159
Enum (0, 1 or 2) corresponding to the type of rectangle found
160+
122161
0. Correctly formated rectangle
123162
1. Wrong perspective, bad angle
124-
2. Too far
125-
163+
1. Too far
126164

127165
## Returned image
128166

129-
| Prop | Params | Type | Description |
130-
| :----------- |:-------:| :--------:| :----------|
131-
| onPictureTaken | `data` | `object` | Returns the captured image in an object `{ croppedImage: ('URI or BASE64 string'), initialImage: 'URI or BASE64 string', rectangleCoordinates: 'object of coordinates' }` |
167+
| Prop | Params | Type | Description |
168+
| :------------- | :----: | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
169+
| onPictureTaken | `data` | `object` | Returns the captured image in an object `{ croppedImage: ('URI or BASE64 string'), initialImage: 'URI or BASE64 string', rectangleCoordinates: 'object of coordinates' }` |
132170

133171
## Save in app document
134172

135-
![Demo save document](images/demoSaveDocument.png)
136-
137173
If you want to use saveInAppDocument options, then don't forget to add those raws in .plist :
174+
138175
```xml
139176
<key>LSSupportsOpeningDocumentsInPlace</key>
140177
<true/>
141178
```
142-
143-
### If you prefer manual installation
144-
145-
1. In XCode, in the project navigator, right click `Libraries``Add Files to [your project's name]`
146-
2. Go to `node_modules``react-native-pdf-scanner` and add `RNPdfScanner.xcodeproj`
147-
3. In XCode, in the project navigator, select your project. Add `libRNPdfScanner.a` to your project's `Build Phases``Link Binary With Libraries`
148-
4. Run your project (`Cmd+R`)<

android.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React, { PureComponent } from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import {
5+
DeviceEventEmitter, // android
6+
NativeModules,
7+
requireNativeComponent,
8+
View
9+
} from 'react-native';
10+
11+
var iface = {
12+
name: 'DocumentScanner',
13+
propTypes: {
14+
documentAnimation : PropTypes.bool,
15+
detectionCountBeforeCapture : PropTypes.number,
16+
enableTorch : PropTypes.bool,
17+
manualOnly: PropTypes.bool,
18+
overlayColor: PropTypes.string,
19+
contrast: PropTypes.number,
20+
brightness: PropTypes.number,
21+
noGrayScale: PropTypes.bool,
22+
...View.propTypes // include the default view properties
23+
},
24+
};
25+
26+
const DocumentScanner = requireNativeComponent('DocumentScanner', iface);
27+
const CameraManager = NativeModules.DocumentScannerManager || {};
28+
29+
class Scanner extends PureComponent{
30+
31+
static defaultProps = {
32+
onPictureTaken: ()=>{},
33+
onProcessing: ()=>{},
34+
}
35+
36+
componentWillMount(){
37+
const { onPictureTaken, onProcessing } = this.props;
38+
DeviceEventEmitter.addListener('onPictureTaken', onPictureTaken);
39+
DeviceEventEmitter.addListener('onProcessingChange', onProcessing);
40+
}
41+
42+
componentWillUnmount(){
43+
const { onPictureTaken, onProcessing } = this.props;
44+
DeviceEventEmitter.removeListener('onPictureTaken', onPictureTaken);
45+
DeviceEventEmitter.removeListener('onProcessingChange', onProcessing);
46+
}
47+
48+
capture = ()=>{
49+
CameraManager.capture();
50+
}
51+
52+
render(){
53+
return <DocumentScanner {...this.props}/>
54+
}
55+
}
56+
57+
export default Scanner;

android/.classpath

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
4+
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
5+
<classpathentry kind="output" path="bin/default"/>
6+
</classpath>

android/.project

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>react-native-document-scanner</name>
4+
<comment>Project react-native-documentscanner-android created by Buildship.</comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
<buildCommand>
14+
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
15+
<arguments>
16+
</arguments>
17+
</buildCommand>
18+
</buildSpec>
19+
<natures>
20+
<nature>org.eclipse.jdt.core.javanature</nature>
21+
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
22+
</natures>
23+
</projectDescription>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
connection.project.dir=
2+
eclipse.preferences.version=1

android/build.gradle

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,40 @@
1+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
12

23
buildscript {
34
repositories {
45
jcenter()
56
}
6-
77
dependencies {
8-
classpath 'com.android.tools.build:gradle:1.3.1'
8+
classpath 'com.android.tools.build:gradle:2.2.3'
9+
10+
// NOTE: Do not place your application dependencies here; they belong
11+
// in the individual module build.gradle files
912
}
1013
}
1114

1215
apply plugin: 'com.android.library'
1316

1417
android {
15-
compileSdkVersion 23
16-
buildToolsVersion "23.0.1"
18+
compileSdkVersion 26
1719

1820
defaultConfig {
1921
minSdkVersion 16
2022
targetSdkVersion 22
2123
versionCode 1
2224
versionName "1.0"
23-
}
24-
lintOptions {
25-
abortOnError false
25+
ndk {
26+
abiFilters "armeabi-v7a", "x86"
27+
}
2628
}
2729
}
2830

29-
repositories {
30-
mavenCentral()
31-
}
32-
3331
dependencies {
34-
compile 'com.facebook.react:react-native:+'
35-
}
36-
32+
implementation project(':openCVLibrary310')
33+
implementation 'com.android.support:appcompat-v7:26.1.0'
34+
implementation 'com.facebook.react:react-native:0.19.+'
35+
implementation 'com.google.zxing:core:3.0.1'
36+
// implementation 'com.android.support:design:26.1.0'
37+
implementation 'org.piwik.sdk:piwik-sdk:0.0.4'
38+
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
39+
implementation 'us.feras.mdv:markdownview:1.1.0'
40+
}

0 commit comments

Comments
 (0)