├── .gitattributes
├── .gitignore
├── .vscode
└── settings.json
├── README.md
├── android
├── .project
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── io
│ └── pickupp
│ └── recatnativeopencv
│ ├── RNOpenCVModule.java
│ └── RNOpenCVPackage.java
├── index.js
├── ios
├── PrefixHeader.pch
├── RNOpenCV.h
├── RNOpenCV.mm
├── RNOpenCV.xcodeproj
│ └── project.pbxproj
└── RNOpenCV.xcworkspace
│ └── contents.xcworkspacedata
├── package.json
└── react-native-opencv.podspec
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # OSX
3 | #
4 | .DS_Store
5 |
6 | # node.js
7 | #
8 | node_modules/
9 | npm-debug.log
10 | yarn-error.log
11 |
12 |
13 | # Xcode
14 | #
15 | build/
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 | xcuserdata
25 | *.xccheckout
26 | *.moved-aside
27 | DerivedData
28 | *.hmap
29 | *.ipa
30 | *.xcuserstate
31 | project.xcworkspace
32 |
33 |
34 | # Android/IntelliJ
35 | #
36 | build/
37 | .idea
38 | .gradle
39 | local.properties
40 | *.iml
41 |
42 | # BUCK
43 | buck-out/
44 | \.buckd/
45 | *.keystore
46 |
47 | # gradle
48 | gradlew
49 | gradlew.bat
50 | import-summary.txt
51 | gradle/
52 | *.so
53 | *.zip
54 |
55 | # sdk
56 | android/libraries/opencv/src/main/java
57 | android/libraries/opencv/src/main/res
58 | android/libraries/opencv/src/main/AndroidManifest.xml
59 | .settings
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "java.configuration.updateBuildConfiguration": "automatic"
3 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # @pickupp/react-native-opencv
3 |
4 | ## Getting started
5 |
6 | `$ npm install @pickupp/react-native-opencv --save`
7 |
8 | ### Mostly automatic installation
9 |
10 | `$ react-native link @pickupp/react-native-opencv`
11 |
12 | ### Prerequisite
13 |
14 | You can directly install the package but it will take a while for downloading the sdk required,
15 | you can download the sdk first and create a enviornment variable `export OPENCV_ANDROID_SDK=/path/to/sdk`
16 |
17 | ### Manual installation
18 |
19 |
20 | #### iOS
21 |
22 | # RN <0.60
23 |
24 | 1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
25 | 2. Go to `node_modules` ➜ `@pickupp/react-native-opencv` and add `RNOpenCV.xcodeproj`
26 | 3. In XCode, in the project navigator, select your project. Add `libRNOpenCV.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`
27 | 4. Run your project (`Cmd+R`)
28 |
29 | #### Android
30 |
31 | # RN >= 0.60
32 |
33 | 1. Open up `android/app/src/main/java/[...]/MainActivity.java`
34 | - Add
35 | ```
36 | import org.opencv.android.BaseLoaderCallback;
37 | import org.opencv.android.LoaderCallbackInterface;
38 | import org.opencv.android.OpenCVLoader;
39 | ```
40 | - Add
41 | ```
42 | private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
43 | @Override
44 | public void onManagerConnected(int status) {
45 | switch (status) {
46 | case LoaderCallbackInterface.SUCCESS:
47 | {
48 | Log.i("OpenCV", "OpenCV loaded successfully");
49 | } break;
50 | default:
51 | {
52 | super.onManagerConnected(status);
53 | } break;
54 | }
55 | }
56 | };
57 |
58 | public void onCreate() {
59 | super.onCreate();
60 | if (!OpenCVLoader.initDebug()) {
61 | Log.d("OpenCv", "Error while init");
62 | }
63 | }
64 |
65 | public void onResume()
66 | {
67 | if (!OpenCVLoader.initDebug()) {
68 | Log.d("OpenCV", "Internal OpenCV library not found. Using OpenCV Manager for initialization");
69 | OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
70 | } else {
71 | Log.d("OpenCV", "OpenCV library found inside package. Using it!");
72 | mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
73 | }
74 | }
75 | ```
76 | 2. Insert the following lines inside the dependencies block in `android/build.gradle` under `allProjects -> dependencies`:
77 | ```
78 | maven {
79 | url "https://dl.bintray.com/pickuppdev/pickupp"
80 | }
81 | ```
82 |
83 | 3. Insert the following lines inside the dependencies block in `android/app/build.gradle` under `allProjects -> dependencies`:
84 | ```
85 | implementation 'org.opencv.android:opencv-android-sdk:3.4.+'
86 | ```
87 |
88 | # RN < 0.60
89 |
90 | 1. Open up `android/app/src/main/java/[...]/MainActivity.java`
91 | - Add `import io.pickupp.recatnativeopencv.RNOpenCVPackage;` to the imports at the top of the file
92 | - Add `new RNOpenCVPackage()` to the list returned by the `getPackages()` method
93 | - Add
94 | ```
95 | import org.opencv.android.BaseLoaderCallback;
96 | import org.opencv.android.LoaderCallbackInterface;
97 | import org.opencv.android.OpenCVLoader;
98 | ```
99 | - Add
100 | ```
101 | private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
102 | @Override
103 | public void onManagerConnected(int status) {
104 | switch (status) {
105 | case LoaderCallbackInterface.SUCCESS:
106 | {
107 | Log.i("OpenCV", "OpenCV loaded successfully");
108 | } break;
109 | default:
110 | {
111 | super.onManagerConnected(status);
112 | } break;
113 | }
114 | }
115 | };
116 |
117 | public void onCreate() {
118 | super.onCreate();
119 | if (!OpenCVLoader.initDebug()) {
120 | Log.d("OpenCv", "Error while init");
121 | }
122 | }
123 |
124 | public void onResume()
125 | {
126 | if (!OpenCVLoader.initDebug()) {
127 | Log.d("OpenCV", "Internal OpenCV library not found. Using OpenCV Manager for initialization");
128 | OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
129 | } else {
130 | Log.d("OpenCV", "OpenCV library found inside package. Using it!");
131 | mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
132 | }
133 | }
134 | ```
135 | 2. Append the following lines to `android/settings.gradle`:
136 | ```
137 | include ':react-native-opencv'
138 | project(':react-native-opencv').projectDir = new File(rootProject.projectDir, '../node_modules/@pickupp/react-native-opencv/android')
139 | include ':opencv-android-sdk'
140 | project(':opencv-android-sdk').projectDir = new File(rootProject.projectDir, '../node_modules/@pickupp/react-native-opencv/android/libraries/opencv')
141 | ```
142 | 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
143 | ```
144 | implementation project(':react-native-opencv')
145 | implementation project(':opencv-android-sdk')
146 | ```
147 | 4. Insert the following lines inside the android block `andriod/app/build.gradle`
148 | ```
149 | sourceSets.main {
150 | // include opencv native jni
151 | jniLibs.srcDir '../../node_modules/@pickupp/react-native-opencv/android/libraries/opencv/jniLibs'
152 | jni.srcDirs = [] //disable automatic ndk-build call
153 | }
154 | ```
155 |
156 | ## Usage
157 | ```javascript
158 | import RNOpenCV from '@pickupp/react-native-opencv';
159 |
160 | const maxEdgeLength = await RNOpenCV.findMaxEdge(/* base64ImageString */)
161 | const laplacianScore = await RNOpenCV.laplacianBlurryCheck(/* base64ImageString */)
162 | ```
163 |
164 |
--------------------------------------------------------------------------------
/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | android
4 | Project android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.3.1'
9 | }
10 | }
11 |
12 | apply plugin: 'com.android.library'
13 |
14 | android {
15 | compileSdkVersion 27
16 | buildToolsVersion "27.0.3"
17 |
18 | defaultConfig {
19 | minSdkVersion 16
20 | targetSdkVersion 27
21 | }
22 | lintOptions {
23 | abortOnError false
24 | }
25 | }
26 |
27 | repositories {
28 | mavenCentral()
29 | }
30 |
31 | dependencies {
32 | implementation 'com.facebook.react:react-native:+'
33 | implementation 'org.opencv.android:opencv-android-sdk:3.4.+'
34 | }
35 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/src/main/java/io/pickupp/recatnativeopencv/RNOpenCVModule.java:
--------------------------------------------------------------------------------
1 | package io.pickupp.recatnativeopencv;
2 |
3 | import com.facebook.react.bridge.ReactApplicationContext;
4 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
5 | import com.facebook.react.bridge.ReactMethod;
6 | import com.facebook.react.bridge.Promise;
7 |
8 | import java.util.List;
9 | import java.util.ArrayList;
10 |
11 | import android.graphics.Bitmap;
12 | import android.graphics.BitmapFactory;
13 |
14 | import org.opencv.core.CvType;
15 | import org.opencv.core.Mat;
16 | import org.opencv.core.MatOfPoint;
17 | import org.opencv.core.MatOfPoint2f;
18 | import org.opencv.core.Size;
19 | import org.opencv.core.Point;
20 | import org.opencv.android.Utils;
21 | import org.opencv.imgproc.Imgproc;
22 |
23 | import android.util.Base64;
24 |
25 | public class RNOpenCVModule extends ReactContextBaseJavaModule {
26 |
27 | private final ReactApplicationContext reactContext;
28 |
29 | public RNOpenCVModule(ReactApplicationContext reactContext) {
30 | super(reactContext);
31 | this.reactContext = reactContext;
32 | }
33 |
34 | @Override
35 | public String getName() {
36 | return "RNOpenCV";
37 | }
38 |
39 | public Mat imageBase64ToMat(String imageAsBase64) {
40 | BitmapFactory.Options options = new BitmapFactory.Options();
41 | options.inDither = true;
42 | options.inPreferredConfig = Bitmap.Config.ARGB_8888;
43 |
44 | byte[] decodedString = Base64.decode(imageAsBase64, Base64.DEFAULT);
45 | Bitmap image = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
46 | Mat matImage = new Mat();
47 | Utils.bitmapToMat(image, matImage);
48 |
49 | return matImage;
50 | }
51 |
52 | @ReactMethod
53 | public void laplacianBlurryCheck(String imageAsBase64, Promise promise) {
54 | try {
55 | // https://stackoverflow.com/questions/36862451/opencv-with-laplacian-formula-to-detect-image-is-blur-or-not-in-android
56 | Mat matImage = this.imageBase64ToMat(imageAsBase64);
57 | int l = CvType.CV_8UC1; //8-bit grey scale image
58 | Mat matImageGrey = new Mat();
59 | Imgproc.cvtColor(matImage, matImageGrey, Imgproc.COLOR_BGR2GRAY);
60 |
61 | Mat laplacianImage = new Mat();
62 | matImage.convertTo(laplacianImage, l);
63 | Imgproc.Laplacian(matImageGrey, laplacianImage, CvType.CV_8U);
64 | Mat laplacianImage8bit = new Mat();
65 | laplacianImage.convertTo(laplacianImage8bit, l);
66 |
67 | int size = (int)(laplacianImage8bit.elemSize() * laplacianImage8bit.total());
68 | byte[] pixels = new byte[size];
69 | laplacianImage8bit.get(0, 0, pixels);
70 | int maxLap = 0;
71 | for (byte pixel : pixels) {
72 | int value = pixel & 0xFF;
73 | if (value > maxLap) {
74 | maxLap = value;
75 | }
76 | }
77 |
78 | promise.resolve(maxLap);
79 | } catch (Exception e) {
80 | promise.reject("unable to calculate laplacian score", e);
81 | }
82 | }
83 |
84 | @ReactMethod
85 | public void findMaxEdge(String imageAsBase64, Promise promise) {
86 | try {
87 | Mat matImage = this.imageBase64ToMat(imageAsBase64);
88 | Mat matImageGrey = new Mat();
89 | Imgproc.cvtColor(matImage, matImageGrey, Imgproc.COLOR_BGR2GRAY);
90 | Imgproc.GaussianBlur(matImageGrey, matImageGrey, new Size(9, 9), 2, 2);
91 |
92 | Mat canny = new Mat();
93 | Imgproc.Canny(matImageGrey, canny, 50, 100, 3);
94 | List contours = new ArrayList<>();
95 | Mat hierarchy = new Mat();
96 | // Imgproc.CV_RETR_TREE: 3
97 | // CV_CHAIN_APPROX_NONE: 1
98 | Imgproc.findContours(canny, contours, hierarchy, 3, 1);
99 |
100 | double maxLength = 0;
101 | for (MatOfPoint edge : contours) {
102 | MatOfPoint2f newEdge = new MatOfPoint2f(edge.toArray());
103 | double value = Imgproc.arcLength(newEdge, false);
104 | if (value > maxLength) {
105 | maxLength = value;
106 | }
107 | }
108 |
109 | promise.resolve(maxLength);
110 | } catch (Exception e) {
111 | promise.reject("unable to find max edge", e);
112 | }
113 | }
114 |
115 | // TODO: implement other methods
116 | }
117 |
--------------------------------------------------------------------------------
/android/src/main/java/io/pickupp/recatnativeopencv/RNOpenCVPackage.java:
--------------------------------------------------------------------------------
1 | package io.pickupp.recatnativeopencv;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collections;
5 | import java.util.List;
6 |
7 | import com.facebook.react.ReactPackage;
8 | import com.facebook.react.bridge.NativeModule;
9 | import com.facebook.react.bridge.ReactApplicationContext;
10 | import com.facebook.react.uimanager.ViewManager;
11 | import com.facebook.react.bridge.JavaScriptModule;
12 | public class RNOpenCVPackage implements ReactPackage {
13 | @Override
14 | public List createNativeModules(ReactApplicationContext reactContext) {
15 | return Arrays.asList(new RNOpenCVModule(reactContext));
16 | }
17 |
18 | // Deprecated from RN 0.47
19 | public List> createJSModules() {
20 | return Collections.emptyList();
21 | }
22 |
23 | @Override
24 | public List createViewManagers(ReactApplicationContext reactContext) {
25 | return Collections.emptyList();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native'
2 |
3 | export default NativeModules.RNOpenCV
4 |
--------------------------------------------------------------------------------
/ios/PrefixHeader.pch:
--------------------------------------------------------------------------------
1 | #ifndef PrefixHeader_pch
2 | #define PrefixHeader_pch
3 |
4 | #ifdef __cplusplus
5 | #import
6 | #endif
7 |
8 | #endif
--------------------------------------------------------------------------------
/ios/RNOpenCV.h:
--------------------------------------------------------------------------------
1 | #if __has_include("RCTBridgeModule.h")
2 | #import "RCTBridgeModule.h"
3 | #else
4 | #import
5 | #endif
6 |
7 | #import
8 |
9 | @interface RNOpenCV : NSObject
10 |
11 | @end
12 |
--------------------------------------------------------------------------------
/ios/RNOpenCV.mm:
--------------------------------------------------------------------------------
1 | #import "RNOpenCV.h"
2 | #import
3 | #import
4 | #import
5 | #import
6 | #import
7 |
8 | @implementation RNOpenCV
9 |
10 | - (dispatch_queue_t)methodQueue {
11 | return dispatch_get_main_queue();
12 | }
13 | RCT_EXPORT_MODULE()
14 |
15 | RCT_EXPORT_METHOD(laplacianBlurryCheck
16 | : (NSString *)imageAsBase64 resolver
17 | : (RCTPromiseResolveBlock)resolve rejecter
18 | : (RCTPromiseRejectBlock)reject) {
19 | @try {
20 | UIImage *image = [self decodeBase64ToImage:imageAsBase64];
21 |
22 | UInt8 laplacianScore = [self laplacianBlurryCheck:image];
23 |
24 | resolve([NSNumber numberWithInt:laplacianScore]);
25 | } @catch (NSException *exception) {
26 | NSError *error;
27 | reject(@"error", exception.reason, error);
28 | }
29 | }
30 |
31 | RCT_EXPORT_METHOD(tenengradBlurryCheck
32 | : (NSString *)imageAsBase64 resolver
33 | : (RCTPromiseResolveBlock)resolve rejecter
34 | : (RCTPromiseRejectBlock)reject) {
35 | NSError *error;
36 | UIImage *image = [self decodeBase64ToImage:imageAsBase64];
37 |
38 | int tenengradScore = [self tenengradBlurryCheck:image];
39 |
40 | if (tenengradScore) {
41 | resolve([NSNumber numberWithDouble:tenengradScore]);
42 | } else {
43 | reject(@"invaild_score", @"Cannot calculate tenegrad score", error);
44 | }
45 | }
46 |
47 | RCT_EXPORT_METHOD(brennerBlurryCheck
48 | : (NSString *)imageAsBase64 resolver
49 | : (RCTPromiseResolveBlock)resolve rejecter
50 | : (RCTPromiseRejectBlock)reject) {
51 | NSError *error;
52 | UIImage *image = [self decodeBase64ToImage:imageAsBase64];
53 |
54 | int brennerScore = [self brennerBlurryCheck:image];
55 |
56 | if (brennerScore) {
57 | resolve([NSNumber numberWithFloat:brennerScore]);
58 | } else {
59 | reject(@"invaild_score", @"Cannot calculate brenner score", error);
60 | }
61 | }
62 |
63 | RCT_EXPORT_METHOD(stdevBlurryCheck
64 | : (NSString *)imageAsBase64 resolver
65 | : (RCTPromiseResolveBlock)resolve rejecter
66 | : (RCTPromiseRejectBlock)reject) {
67 | NSError *error;
68 | UIImage *image = [self decodeBase64ToImage:imageAsBase64];
69 |
70 | int stdevScore = [self stdevBlurryCheck:image];
71 |
72 | if (stdevScore) {
73 | resolve([NSNumber numberWithDouble:stdevScore]);
74 | } else {
75 | reject(@"invaild_score", @"Cannot calculate stdev score", error);
76 | }
77 | }
78 |
79 | RCT_EXPORT_METHOD(entropyBlurryCheck
80 | : (NSString *)imageAsBase64 resolver
81 | : (RCTPromiseResolveBlock)resolve rejecter
82 | : (RCTPromiseRejectBlock)reject) {
83 | NSError *error;
84 | UIImage *image = [self decodeBase64ToImage:imageAsBase64];
85 |
86 | int entropyScore = [self entropyBlurryCheck:image];
87 |
88 | if (entropyScore) {
89 | resolve([NSNumber numberWithDouble:entropyScore]);
90 | } else {
91 | reject(@"invaild_score", @"Cannot calculate entropy score", error);
92 | }
93 | }
94 |
95 | RCT_EXPORT_METHOD(findMaxEdge
96 | : (NSString *)imageAsBase64 resolver
97 | : (RCTPromiseResolveBlock)resolve rejecter
98 | : (RCTPromiseRejectBlock)reject) {
99 | @try {
100 | UIImage *image = [self decodeBase64ToImage:imageAsBase64];
101 | cv::Mat matImage = [self convertUIImageToCVMat:image];
102 |
103 | double laplacianScore = [self findMaxEdge:&matImage];
104 |
105 | resolve([NSNumber numberWithDouble:laplacianScore]);
106 | } @catch (NSException *exception) {
107 | NSError *error;
108 | reject(@"error", exception.reason, error);
109 | }
110 | }
111 |
112 | // native code
113 | - (NSString *)imageToNSString:(UIImage *)image {
114 | NSData *imageData = UIImagePNGRepresentation(image);
115 |
116 | return [imageData
117 | base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
118 | }
119 | - (cv::Mat)convertUIImageToCVMat:(UIImage *)image {
120 | CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
121 | CGFloat cols = image.size.width;
122 | CGFloat rows = image.size.height;
123 |
124 | cv::Mat cvMat(
125 | rows, cols,
126 | CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha)
127 |
128 | CGContextRef contextRef =
129 | CGBitmapContextCreate(cvMat.data, // Pointer to data
130 | cols, // Width of bitmap
131 | rows, // Height of bitmap
132 | 8, // Bits per component
133 | cvMat.step[0], // Bytes per row
134 | colorSpace, // Colorspace
135 | kCGImageAlphaNoneSkipLast |
136 | kCGBitmapByteOrderDefault); // Bitmap info flags
137 |
138 | CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
139 | CGContextRelease(contextRef);
140 |
141 | return cvMat;
142 | }
143 |
144 | - (UIImage *)decodeBase64ToImage:(NSString *)strEncodeData {
145 | NSData *data = [[NSData alloc]
146 | initWithBase64EncodedString:strEncodeData
147 | options:NSDataBase64DecodingIgnoreUnknownCharacters];
148 | return [UIImage imageWithData:data];
149 | }
150 |
151 | - (UInt8)laplacianBlurryCheck:(UIImage *)image {
152 | // converting UIImage to OpenCV format - Mat
153 | cv::Mat matImage = [self convertUIImageToCVMat:image];
154 | cv::Mat matImageGrey;
155 | // converting image's color space (RGB) to grayscale
156 | cv::cvtColor(matImage, matImageGrey, CV_BGR2GRAY);
157 |
158 | cv::Mat laplacianImage;
159 | matImage.convertTo(laplacianImage, CV_8UC1);
160 |
161 | // applying Laplacian operator to the image
162 | cv::Laplacian(matImageGrey, laplacianImage, CV_8U);
163 | cv::Mat laplacianImage8bit;
164 | laplacianImage.convertTo(laplacianImage8bit, CV_8UC1);
165 |
166 | unsigned char *pixels = laplacianImage8bit.data;
167 |
168 | // 16777216 = 256*256*256
169 | UInt8 maxLap = 0;
170 | for (int i = 0;
171 | i < (laplacianImage8bit.elemSize() * laplacianImage8bit.total()); i++) {
172 | if (pixels[i] > maxLap) {
173 | maxLap = pixels[i];
174 | }
175 | }
176 | // one of the main parameters here: threshold sets the sensitivity for the
177 | // blur check smaller number = less sensitive; default = 180
178 |
179 | return maxLap;
180 | }
181 |
182 | - (UInt8)laplacianProcess:(cv::Mat *)matImage
183 | laplacianImage:(cv::Mat *)singleChannel {
184 | cv::Mat laplacianImage;
185 | matImage->convertTo(laplacianImage, CV_8UC1);
186 |
187 | // applying Laplacian operator to the image
188 | cv::Laplacian(*singleChannel, laplacianImage, CV_8U);
189 | cv::Mat laplacianImageBlue;
190 | laplacianImage.convertTo(laplacianImageBlue, CV_8UC1);
191 |
192 | unsigned char *bluePixels = laplacianImageBlue.data;
193 |
194 | UInt8 maxLap = 0;
195 | for (int i = 0; i < (singleChannel->elemSize() * singleChannel->total());
196 | i++) {
197 | if (bluePixels[i] > maxLap) {
198 | maxLap = bluePixels[i];
199 | }
200 | }
201 | return maxLap;
202 | }
203 |
204 | - (double)tenengradBlurryCheck:(UIImage *)image {
205 | // converting UIImage to OpenCV format - Mat
206 | cv::Mat matImage = [self convertUIImageToCVMat:image];
207 | cv::Mat matImageGrey;
208 | // converting image's color space (RGB) to grayscale
209 | cv::cvtColor(matImage, matImageGrey, CV_BGR2GRAY);
210 |
211 | cv::Mat imageSobel;
212 | Sobel(matImageGrey, imageSobel, CV_16U, 1, 1);
213 | double meanValue = 0.0;
214 | meanValue = mean(imageSobel)[0];
215 |
216 | return meanValue;
217 | }
218 |
219 | - (float)brennerBlurryCheck:(UIImage *)image {
220 | // converting UIImage to OpenCV format - Mat
221 | cv::Mat matImage = [self convertUIImageToCVMat:image];
222 | cv::Mat matImageGrey;
223 | // converting image's color space (RGB) to grayscale
224 | cv::cvtColor(matImage, matImageGrey, CV_BGR2GRAY);
225 |
226 | // Brenner's Algorithm
227 |
228 | cv::Size s = matImageGrey.size();
229 | int rows = s.height;
230 | int cols = s.width;
231 | cv::Mat DH = cv::Mat(rows, cols, CV_64F, double(0));
232 | cv::Mat DV = cv::Mat(rows, cols, CV_64F, double(0));
233 | cv::subtract(matImageGrey.rowRange(2, rows).colRange(0, cols),
234 | matImageGrey.rowRange(0, rows - 2).colRange(0, cols),
235 | DV.rowRange(0, rows - 2).colRange(0, cols));
236 | cv::subtract(matImageGrey.rowRange(0, rows).colRange(2, cols),
237 | matImageGrey.rowRange(0, rows).colRange(0, cols - 2),
238 | DH.rowRange(0, rows).colRange(0, cols - 2));
239 |
240 | cv::Mat FM = cv::max(DH, DV);
241 | FM = FM.mul(FM);
242 | cv::Scalar tempVal = mean(FM);
243 | float myMatMean = tempVal.val[0];
244 | return myMatMean;
245 | }
246 |
247 | - (double)stdevBlurryCheck:(UIImage *)image {
248 | // converting UIImage to OpenCV format - Mat
249 | cv::Mat matImage = [self convertUIImageToCVMat:image];
250 | cv::Mat matImageGrey;
251 | // converting image's color space (RGB) to grayscale
252 | cv::cvtColor(matImage, matImageGrey, CV_BGR2GRAY);
253 |
254 | cv::Mat meanValueImage;
255 | cv::Mat meanStdValueImage;
256 | meanStdDev(matImageGrey, meanValueImage, meanStdValueImage);
257 | double meanValue = 0.0;
258 | meanValue = meanStdValueImage.at(0, 0);
259 |
260 | return meanValue;
261 | }
262 |
263 | - (double)entropyBlurryCheck:(UIImage *)image {
264 | // converting UIImage to OpenCV format - Mat
265 | cv::Mat matImage = [self convertUIImageToCVMat:image];
266 | // allocate memory
267 | double temp[256] = {0.0};
268 |
269 | // calculate acc. value for each row
270 | for (int m = 0; m < matImage.rows; m++) { // look over cols
271 | const uchar *t = matImage.ptr(m);
272 | for (int n = 0; n < matImage.cols; n++) {
273 | int i = t[n];
274 | temp[i] = temp[i] + 1;
275 | }
276 | }
277 |
278 | // calculate over pixels
279 | for (int i = 0; i < 256; i++) {
280 | temp[i] = temp[i] / (matImage.rows * matImage.cols);
281 | }
282 |
283 | double result = 0;
284 | // calculate logs
285 | for (int i = 0; i < 256; i++) {
286 | if (temp[i] == 0.0)
287 | result = result;
288 | else
289 | result = result - temp[i] * (log(temp[i]) / log(2.0));
290 | }
291 |
292 | return result;
293 | }
294 |
295 | - (double)findMaxEdge:(cv::Mat *)matImage {
296 | // converting UIImage to OpenCV format - Mat
297 | cv::Mat matImageGrey;
298 | // converting image's color space (RGB) to grayscale
299 | cv::cvtColor(*matImage, matImageGrey, CV_BGR2GRAY);
300 |
301 | // This is done so as to prevent a lot of false circles from being detected
302 | cv::GaussianBlur(matImageGrey, matImageGrey, cv::Size(9, 9), 2, 2);
303 |
304 | cv::Mat canny = cv::Mat(matImage->size(), CV_8UC1);
305 | cv::Canny(matImageGrey, canny, 50, 100, 3);
306 |
307 | std::vector> contours;
308 | std::vector hierarchy;
309 | cv::findContours(canny, contours, hierarchy, CV_RETR_TREE,
310 | CV_CHAIN_APPROX_NONE);
311 | double maxLength = 0;
312 |
313 | for (int i = 0; i < contours.size(); i++) {
314 | double edgeLenght = cv::arcLength(contours[i], FALSE);
315 | if (edgeLenght > maxLength) {
316 | maxLength = edgeLenght;
317 | }
318 | }
319 |
320 | return maxLength;
321 | }
322 |
323 | @end
324 |
--------------------------------------------------------------------------------
/ios/RNOpenCV.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B3E7B58A1CC2AC0600A0062D /* RNOpenCV.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNOpenCV.mm */; };
11 | /* End PBXBuildFile section */
12 |
13 | /* Begin PBXCopyFilesBuildPhase section */
14 | 58B511D91A9E6C8500147676 /* CopyFiles */ = {
15 | isa = PBXCopyFilesBuildPhase;
16 | buildActionMask = 2147483647;
17 | dstPath = "include/$(PRODUCT_NAME)";
18 | dstSubfolderSpec = 16;
19 | files = (
20 | );
21 | runOnlyForDeploymentPostprocessing = 0;
22 | };
23 | /* End PBXCopyFilesBuildPhase section */
24 |
25 | /* Begin PBXFileReference section */
26 | 134814201AA4EA6300B7C361 /* libRNOpenCV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNOpenCV.a; sourceTree = BUILT_PRODUCTS_DIR; };
27 | B3E7B5881CC2AC0600A0062D /* RNOpenCV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNOpenCV.h; sourceTree = ""; };
28 | B3E7B5891CC2AC0600A0062D /* RNOpenCV.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNOpenCV.mm; sourceTree = ""; };
29 | /* End PBXFileReference section */
30 |
31 | /* Begin PBXFrameworksBuildPhase section */
32 | 58B511D81A9E6C8500147676 /* Frameworks */ = {
33 | isa = PBXFrameworksBuildPhase;
34 | buildActionMask = 2147483647;
35 | files = (
36 | );
37 | runOnlyForDeploymentPostprocessing = 0;
38 | };
39 | /* End PBXFrameworksBuildPhase section */
40 |
41 | /* Begin PBXGroup section */
42 | 134814211AA4EA7D00B7C361 /* Products */ = {
43 | isa = PBXGroup;
44 | children = (
45 | 134814201AA4EA6300B7C361 /* libRNOpenCV.a */,
46 | );
47 | name = Products;
48 | sourceTree = "";
49 | };
50 | 58B511D21A9E6C8500147676 = {
51 | isa = PBXGroup;
52 | children = (
53 | B3E7B5881CC2AC0600A0062D /* RNOpenCV.h */,
54 | B3E7B5891CC2AC0600A0062D /* RNOpenCV.mm */,
55 | 134814211AA4EA7D00B7C361 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | /* End PBXGroup section */
60 |
61 | /* Begin PBXNativeTarget section */
62 | 58B511DA1A9E6C8500147676 /* RNOpenCV */ = {
63 | isa = PBXNativeTarget;
64 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNOpenCV" */;
65 | buildPhases = (
66 | 58B511D71A9E6C8500147676 /* Sources */,
67 | 58B511D81A9E6C8500147676 /* Frameworks */,
68 | 58B511D91A9E6C8500147676 /* CopyFiles */,
69 | );
70 | buildRules = (
71 | );
72 | dependencies = (
73 | );
74 | name = RNOpenCV;
75 | productName = RCTDataManager;
76 | productReference = 134814201AA4EA6300B7C361 /* libRNOpenCV.a */;
77 | productType = "com.apple.product-type.library.static";
78 | };
79 | /* End PBXNativeTarget section */
80 |
81 | /* Begin PBXProject section */
82 | 58B511D31A9E6C8500147676 /* Project object */ = {
83 | isa = PBXProject;
84 | attributes = {
85 | LastUpgradeCheck = 1010;
86 | ORGANIZATIONNAME = Facebook;
87 | TargetAttributes = {
88 | 58B511DA1A9E6C8500147676 = {
89 | CreatedOnToolsVersion = 6.1.1;
90 | };
91 | };
92 | };
93 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNOpenCV" */;
94 | compatibilityVersion = "Xcode 3.2";
95 | developmentRegion = English;
96 | hasScannedForEncodings = 0;
97 | knownRegions = (
98 | en,
99 | );
100 | mainGroup = 58B511D21A9E6C8500147676;
101 | productRefGroup = 58B511D21A9E6C8500147676;
102 | projectDirPath = "";
103 | projectRoot = "";
104 | targets = (
105 | 58B511DA1A9E6C8500147676 /* RNOpenCV */,
106 | );
107 | };
108 | /* End PBXProject section */
109 |
110 | /* Begin PBXSourcesBuildPhase section */
111 | 58B511D71A9E6C8500147676 /* Sources */ = {
112 | isa = PBXSourcesBuildPhase;
113 | buildActionMask = 2147483647;
114 | files = (
115 | B3E7B58A1CC2AC0600A0062D /* RNOpenCV.mm in Sources */,
116 | );
117 | runOnlyForDeploymentPostprocessing = 0;
118 | };
119 | /* End PBXSourcesBuildPhase section */
120 |
121 | /* Begin XCBuildConfiguration section */
122 | 58B511ED1A9E6C8500147676 /* Debug */ = {
123 | isa = XCBuildConfiguration;
124 | buildSettings = {
125 | ALWAYS_SEARCH_USER_PATHS = NO;
126 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
127 | CLANG_CXX_LIBRARY = "libc++";
128 | CLANG_ENABLE_MODULES = YES;
129 | CLANG_ENABLE_OBJC_ARC = YES;
130 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
131 | CLANG_WARN_BOOL_CONVERSION = YES;
132 | CLANG_WARN_COMMA = YES;
133 | CLANG_WARN_CONSTANT_CONVERSION = YES;
134 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
135 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
136 | CLANG_WARN_EMPTY_BODY = YES;
137 | CLANG_WARN_ENUM_CONVERSION = YES;
138 | CLANG_WARN_INFINITE_RECURSION = YES;
139 | CLANG_WARN_INT_CONVERSION = YES;
140 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
141 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
142 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
143 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
144 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
145 | CLANG_WARN_STRICT_PROTOTYPES = YES;
146 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
147 | CLANG_WARN_UNREACHABLE_CODE = YES;
148 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
149 | COPY_PHASE_STRIP = NO;
150 | ENABLE_STRICT_OBJC_MSGSEND = YES;
151 | ENABLE_TESTABILITY = YES;
152 | GCC_C_LANGUAGE_STANDARD = gnu99;
153 | GCC_DYNAMIC_NO_PIC = NO;
154 | GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
155 | GCC_NO_COMMON_BLOCKS = YES;
156 | GCC_OPTIMIZATION_LEVEL = 0;
157 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
158 | GCC_PREFIX_HEADER = "$(PROJECT_DIR)/PrefixHeader.pch";
159 | GCC_PREPROCESSOR_DEFINITIONS = (
160 | "DEBUG=1",
161 | "$(inherited)",
162 | );
163 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
164 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
165 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
166 | GCC_WARN_UNDECLARED_SELECTOR = YES;
167 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
168 | GCC_WARN_UNUSED_FUNCTION = YES;
169 | GCC_WARN_UNUSED_VARIABLE = YES;
170 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
171 | MTL_ENABLE_DEBUG_INFO = YES;
172 | ONLY_ACTIVE_ARCH = YES;
173 | SDKROOT = iphoneos;
174 | };
175 | name = Debug;
176 | };
177 | 58B511EE1A9E6C8500147676 /* Release */ = {
178 | isa = XCBuildConfiguration;
179 | buildSettings = {
180 | ALWAYS_SEARCH_USER_PATHS = NO;
181 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
182 | CLANG_CXX_LIBRARY = "libc++";
183 | CLANG_ENABLE_MODULES = YES;
184 | CLANG_ENABLE_OBJC_ARC = YES;
185 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
186 | CLANG_WARN_BOOL_CONVERSION = YES;
187 | CLANG_WARN_COMMA = YES;
188 | CLANG_WARN_CONSTANT_CONVERSION = YES;
189 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
190 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
191 | CLANG_WARN_EMPTY_BODY = YES;
192 | CLANG_WARN_ENUM_CONVERSION = YES;
193 | CLANG_WARN_INFINITE_RECURSION = YES;
194 | CLANG_WARN_INT_CONVERSION = YES;
195 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
196 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
197 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
198 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
199 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
200 | CLANG_WARN_STRICT_PROTOTYPES = YES;
201 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
202 | CLANG_WARN_UNREACHABLE_CODE = YES;
203 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
204 | COPY_PHASE_STRIP = YES;
205 | ENABLE_NS_ASSERTIONS = NO;
206 | ENABLE_STRICT_OBJC_MSGSEND = YES;
207 | GCC_C_LANGUAGE_STANDARD = gnu99;
208 | GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
209 | GCC_NO_COMMON_BLOCKS = YES;
210 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
211 | GCC_PREFIX_HEADER = "$(PROJECT_DIR)/PrefixHeader.pch";
212 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
213 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
214 | GCC_WARN_UNDECLARED_SELECTOR = YES;
215 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
216 | GCC_WARN_UNUSED_FUNCTION = YES;
217 | GCC_WARN_UNUSED_VARIABLE = YES;
218 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
219 | MTL_ENABLE_DEBUG_INFO = NO;
220 | SDKROOT = iphoneos;
221 | VALIDATE_PRODUCT = YES;
222 | };
223 | name = Release;
224 | };
225 | 58B511F01A9E6C8500147676 /* Debug */ = {
226 | isa = XCBuildConfiguration;
227 | buildSettings = {
228 | DEAD_CODE_STRIPPING = NO;
229 | ENABLE_ON_DEMAND_RESOURCES = NO;
230 | FRAMEWORK_SEARCH_PATHS = (
231 | "$(inherited)",
232 | "$(SRCROOT)/../../../ios/Pods",
233 | "$(SRCROOT)/../../../ios",
234 | "$(SRCROOT)/../../../ios/Pods/OpenCV/**",
235 | );
236 | GCC_NO_COMMON_BLOCKS = YES;
237 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
238 | GCC_PREFIX_HEADER = "$(PROJECT_DIR)/PrefixHeader.pch";
239 | GCC_PREPROCESSOR_DEFINITIONS = (
240 | "DEBUG=1",
241 | "$(inherited)",
242 | );
243 | GCC_VERSION = "";
244 | HEADER_SEARCH_PATHS = (
245 | "$(inherited)",
246 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
247 | "$(SRCROOT)/../../../React/**",
248 | "$(SRCROOT)/../../react-native/React/**",
249 | "$(SRCROOT)/../../react-native/React/**",
250 | "$(SRCROOT)/../../react-native/React/**/**",
251 | "$(SRCROOT)/../../../OpenCV/**",
252 | );
253 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
254 | LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
255 | LIBRARY_SEARCH_PATHS = "$(inherited)";
256 | OTHER_CFLAGS = "$(inherited)";
257 | OTHER_LDFLAGS = (
258 | "$(inherited)",
259 | "-ObjC",
260 | "-lc++",
261 | );
262 | PRODUCT_NAME = RNOpenCV;
263 | SKIP_INSTALL = YES;
264 | STRIP_STYLE = all;
265 | TARGETED_DEVICE_FAMILY = "1,2";
266 | };
267 | name = Debug;
268 | };
269 | 58B511F11A9E6C8500147676 /* Release */ = {
270 | isa = XCBuildConfiguration;
271 | buildSettings = {
272 | ENABLE_ON_DEMAND_RESOURCES = NO;
273 | FRAMEWORK_SEARCH_PATHS = (
274 | "$(inherited)",
275 | "$(SRCROOT)/../../../ios/Pods",
276 | "$(SRCROOT)/../../../ios",
277 | "$(SRCROOT)/../../../ios/Pods/OpenCV/**",
278 | );
279 | GCC_NO_COMMON_BLOCKS = YES;
280 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
281 | GCC_PREFIX_HEADER = "$(PROJECT_DIR)/PrefixHeader.pch";
282 | GCC_VERSION = "";
283 | HEADER_SEARCH_PATHS = (
284 | "$(inherited)",
285 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
286 | "$(SRCROOT)/../../../React/**",
287 | "$(SRCROOT)/../../react-native/React/**",
288 | "$(SRCROOT)/../../react-native/React/**",
289 | "$(SRCROOT)/../../react-native/React/**/**",
290 | "$(SRCROOT)/../../../OpenCV/**",
291 | );
292 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
294 | LIBRARY_SEARCH_PATHS = "$(inherited)";
295 | OTHER_CFLAGS = "$(inherited)";
296 | OTHER_LDFLAGS = (
297 | "$(inherited)",
298 | "-ObjC",
299 | "-lc++",
300 | );
301 | PRODUCT_NAME = RNOpenCV;
302 | SKIP_INSTALL = YES;
303 | STRIP_STYLE = all;
304 | TARGETED_DEVICE_FAMILY = "1,2";
305 | };
306 | name = Release;
307 | };
308 | /* End XCBuildConfiguration section */
309 |
310 | /* Begin XCConfigurationList section */
311 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNOpenCV" */ = {
312 | isa = XCConfigurationList;
313 | buildConfigurations = (
314 | 58B511ED1A9E6C8500147676 /* Debug */,
315 | 58B511EE1A9E6C8500147676 /* Release */,
316 | );
317 | defaultConfigurationIsVisible = 0;
318 | defaultConfigurationName = Release;
319 | };
320 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNOpenCV" */ = {
321 | isa = XCConfigurationList;
322 | buildConfigurations = (
323 | 58B511F01A9E6C8500147676 /* Debug */,
324 | 58B511F11A9E6C8500147676 /* Release */,
325 | );
326 | defaultConfigurationIsVisible = 0;
327 | defaultConfigurationName = Release;
328 | };
329 | /* End XCConfigurationList section */
330 | };
331 | rootObject = 58B511D31A9E6C8500147676 /* Project object */;
332 | }
333 |
--------------------------------------------------------------------------------
/ios/RNOpenCV.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 |
3 |
5 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "name": "@pickupp/react-native-opencv",
4 | "version": "1.1.0",
5 | "description": "OpenCV binding for recat-native",
6 | "main": "index.js",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/pickuppdev/react-native-opencv"
13 | },
14 | "homepage": "https://github.com/pickuppdev/react-native-opencv",
15 | "keywords": [
16 | "react-native"
17 | ],
18 | "author": "",
19 | "contributors": [
20 | {
21 | "name": "Allen Ng",
22 | "email": "allen.ng@pickupp.io"
23 | },{
24 | "name": "Lawrence Ho",
25 | "email": "clong@pickupp.io"
26 | }
27 | ],
28 | "license": "MIT",
29 | "peerDependencies": {
30 | "react-native": "^0.41.2"
31 | },
32 | "podName": "react-native-opencv"
33 | }
34 |
--------------------------------------------------------------------------------
/react-native-opencv.podspec:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4 |
5 | Pod::Spec.new do |s|
6 | s.name = package['podName']
7 | s.version = package['version']
8 | s.license = package['license']
9 | s.homepage = package['homepage']
10 | s.authors = package['contributors'].flat_map { |author| { author['name'] => author['email'] } }
11 | s.summary = package['description']
12 | s.source = { :git => package['repository']['url'] }
13 | s.source_files = 'ios/*.{h,m,mm}'
14 | s.platform = :ios, '8.0'
15 | s.requires_arc = true
16 |
17 | s.dependency "React"
18 | s.dependency "OpenCV", '~> 3.4.2'
19 |
20 | end
21 |
22 |
23 |
--------------------------------------------------------------------------------