├── .gitattributes ├── windows ├── .npmignore ├── RNTensorflowLite │ ├── project.json │ ├── RNTensorflowLiteModule.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── RNTensorflowLite.rd.xml │ ├── RNTensorflowLitePackage.cs │ └── RNTensorflowLite.csproj ├── .gitignore └── RNTensorflowLite.sln ├── android ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── rntensorflowlite │ │ ├── RNTensorflowLitePackage.java │ │ ├── Classifier.java │ │ ├── RNTFLiteImageRecognizerModule.java │ │ └── TFLiteImageRecognizer.java └── build.gradle ├── ios ├── RNTensorflowLite.m ├── RNTensorflowLite.h ├── RNTensorflowLite.xcworkspace │ └── contents.xcworkspacedata ├── RNTensorflowLite.podspec └── RNTensorflowLite.xcodeproj │ └── project.pbxproj ├── package.json ├── .gitignore ├── index.js └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text -------------------------------------------------------------------------------- /windows/.npmignore: -------------------------------------------------------------------------------- 1 | 2 | # Make sure we don't publish build artifacts to NPM 3 | ARM/ 4 | Debug/ 5 | x64/ 6 | x86/ 7 | bin/ 8 | obj/ 9 | .vs/ 10 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ios/RNTensorflowLite.m: -------------------------------------------------------------------------------- 1 | 2 | #import "RNTensorflowLite.h" 3 | 4 | @implementation RNTensorflowLite 5 | 6 | - (dispatch_queue_t)methodQueue 7 | { 8 | return dispatch_get_main_queue(); 9 | } 10 | RCT_EXPORT_MODULE() 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /ios/RNTensorflowLite.h: -------------------------------------------------------------------------------- 1 | 2 | #if __has_include("RCTBridgeModule.h") 3 | #import "RCTBridgeModule.h" 4 | #else 5 | #import 6 | #endif 7 | 8 | @interface RNTensorflowLite : NSObject 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /ios/RNTensorflowLite.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | 3 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /windows/RNTensorflowLite/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.2.2" 4 | }, 5 | "frameworks": { 6 | "uap10.0": {} 7 | }, 8 | "runtimes": { 9 | "win10-arm": {}, 10 | "win10-arm-aot": {}, 11 | "win10-x86": {}, 12 | "win10-x86-aot": {}, 13 | "win10-x64": {}, 14 | "win10-x64-aot": {} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-tensorflow-lite", 3 | "version": "1.0.5", 4 | "description": "A react native library for running Tensorflow Lite on Android", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "react-native", 11 | "tensorflow lite", 12 | "tensorflow" 13 | ], 14 | "author": "", 15 | "license": "", 16 | "peerDependencies": { 17 | "react-native": "^0.41.2", 18 | "react-native-windows": "0.41.0-rc.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | buildscript { 3 | repositories { 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.3' 9 | } 10 | } 11 | 12 | apply plugin: 'com.android.library' 13 | 14 | android { 15 | compileSdkVersion 23 16 | buildToolsVersion "23.0.1" 17 | 18 | defaultConfig { 19 | minSdkVersion 16 20 | targetSdkVersion 23 21 | versionCode 1 22 | versionName "1.0" 23 | } 24 | lintOptions { 25 | abortOnError false 26 | } 27 | 28 | } 29 | 30 | repositories { 31 | mavenCentral() 32 | } 33 | 34 | dependencies { 35 | compile 'com.facebook.react:react-native:+' 36 | compile 'org.tensorflow:tensorflow-lite:+' 37 | } 38 | -------------------------------------------------------------------------------- /ios/RNTensorflowLite.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = "RNTensorflowLite" 4 | s.version = "1.0.0" 5 | s.summary = "RNTensorflowLite" 6 | s.description = <<-DESC 7 | RNTensorflowLite 8 | DESC 9 | s.homepage = "" 10 | s.license = "MIT" 11 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 12 | s.author = { "author" => "author@domain.cn" } 13 | s.platform = :ios, "7.0" 14 | s.source = { :git => "https://github.com/author/RNTensorflowLite.git", :tag => "master" } 15 | s.source_files = "RNTensorflowLite/**/*.{h,m}" 16 | s.requires_arc = true 17 | 18 | 19 | s.dependency "React" 20 | #s.dependency "others" 21 | 22 | end 23 | 24 | -------------------------------------------------------------------------------- /windows/RNTensorflowLite/RNTensorflowLiteModule.cs: -------------------------------------------------------------------------------- 1 | using ReactNative.Bridge; 2 | using System; 3 | using System.Collections.Generic; 4 | using Windows.ApplicationModel.Core; 5 | using Windows.UI.Core; 6 | 7 | namespace Tensorflow.Lite.RNTensorflowLite 8 | { 9 | /// 10 | /// A module that allows JS to share data. 11 | /// 12 | class RNTensorflowLiteModule : NativeModuleBase 13 | { 14 | /// 15 | /// Instantiates the . 16 | /// 17 | internal RNTensorflowLiteModule() 18 | { 19 | 20 | } 21 | 22 | /// 23 | /// The name of the native module. 24 | /// 25 | public override string Name 26 | { 27 | get 28 | { 29 | return "RNTensorflowLite"; 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { NativeModules, Image } from 'react-native'; 2 | 3 | const { RNTFLiteImageRecognition } = NativeModules; 4 | 5 | class TFLiteImageRecognition { 6 | constructor(data) { 7 | data['model'] = Image.resolveAssetSource(data['model']) != null 8 | ? Image.resolveAssetSource(data['model']).uri 9 | : data['model'] 10 | 11 | data['labels'] = Image.resolveAssetSource(data['labels']) != null 12 | ? Image.resolveAssetSource(data['labels']).uri 13 | : data['labels'] 14 | 15 | this.state = RNTFLiteImageRecognition.createImageRecognizer(data); 16 | } 17 | 18 | async recognize(data) { 19 | await this.state; 20 | 21 | data['image'] = Image.resolveAssetSource(data['image']) != null 22 | ? Image.resolveAssetSource(data['image']).uri 23 | : data['image'] 24 | 25 | return RNTFLiteImageRecognition.recognize(data); 26 | } 27 | 28 | async close() { 29 | await this.state; 30 | 31 | RNTFLiteImageRecognition.close(); 32 | } 33 | 34 | } 35 | 36 | export { TFLiteImageRecognition }; 37 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | *AppPackages* 2 | *BundleArtifacts* 3 | *ReactAssets* 4 | 5 | #OS junk files 6 | [Tt]humbs.db 7 | *.DS_Store 8 | 9 | #Visual Studio files 10 | *.[Oo]bj 11 | *.user 12 | *.aps 13 | *.pch 14 | *.vspscc 15 | *.vssscc 16 | *_i.c 17 | *_p.c 18 | *.ncb 19 | *.suo 20 | *.tlb 21 | *.tlh 22 | *.bak 23 | *.[Cc]ache 24 | *.ilk 25 | *.log 26 | *.lib 27 | *.sbr 28 | *.sdf 29 | *.opensdf 30 | *.opendb 31 | *.unsuccessfulbuild 32 | ipch/ 33 | [Oo]bj/ 34 | [Bb]in 35 | [Dd]ebug*/ 36 | [Rr]elease*/ 37 | Ankh.NoLoad 38 | 39 | #MonoDevelop 40 | *.pidb 41 | *.userprefs 42 | 43 | #Tooling 44 | _ReSharper*/ 45 | *.resharper 46 | [Tt]est[Rr]esult* 47 | *.sass-cache 48 | 49 | #Project files 50 | [Bb]uild/ 51 | 52 | #Subversion files 53 | .svn 54 | 55 | # Office Temp Files 56 | ~$* 57 | 58 | # vim Temp Files 59 | *~ 60 | 61 | #NuGet 62 | packages/ 63 | *.nupkg 64 | 65 | #ncrunch 66 | *ncrunch* 67 | *crunch*.local.xml 68 | 69 | # visual studio database projects 70 | *.dbmdl 71 | 72 | #Test files 73 | *.testsettings 74 | 75 | #Other files 76 | *.DotSettings 77 | .vs/ 78 | *project.lock.json 79 | -------------------------------------------------------------------------------- /windows/RNTensorflowLite/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RNTensorflowLite")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RNTensorflowLite")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | [assembly: ComVisible(false)] 30 | -------------------------------------------------------------------------------- /android/src/main/java/com/rntensorflowlite/RNTensorflowLitePackage.java: -------------------------------------------------------------------------------- 1 | package com.rntensorflowlite; 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 | import com.rntensorflowlite.imagerecognition.RNTFLiteImageRecognizerModule; 13 | 14 | public class RNTensorflowLitePackage implements ReactPackage { 15 | @Override 16 | public List < NativeModule > createNativeModules(ReactApplicationContext reactContext) { 17 | return Arrays. < NativeModule > asList( 18 | new RNTFLiteImageRecognizerModule(reactContext) 19 | ); 20 | } 21 | 22 | // Deprecated from RN 0.47 23 | public List < Class << ? extends JavaScriptModule >> createJSModules() { 24 | return Collections.emptyList(); 25 | } 26 | 27 | @Override 28 | public List < ViewManager > createViewManagers(ReactApplicationContext reactContext) { 29 | return Collections.emptyList(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /windows/RNTensorflowLite/Properties/RNTensorflowLite.rd.xml: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /android/src/main/java/com/rntensorflowlite/Classifier.java: -------------------------------------------------------------------------------- 1 | package com.rntensorflowlite; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import com.facebook.react.bridge.*; 6 | import java.util.*; 7 | 8 | /** 9 | * Created by amitshekhar on 17/03/18. 10 | */ 11 | 12 | public interface Classifier { 13 | 14 | class Recognition { 15 | /** 16 | * A unique identifier for what has been recognized. Specific to the class, not the instance of 17 | * the object. 18 | */ 19 | private final String id; 20 | 21 | /** 22 | * Display name for the recognition. 23 | */ 24 | private final String title; 25 | 26 | /** 27 | * A sortable score for how good the recognition is relative to others. Higher should be better. 28 | */ 29 | private final Float confidence; 30 | 31 | public Recognition( 32 | final String id, final String title, final Float confidence) { 33 | this.id = id; 34 | this.title = title; 35 | this.confidence = confidence; 36 | } 37 | 38 | public String getId() { 39 | return id; 40 | } 41 | 42 | public String getTitle() { 43 | return title; 44 | } 45 | 46 | public Float getConfidence() { 47 | return confidence; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | String resultString = ""; 53 | if (id != null) { 54 | resultString += "[" + id + "] "; 55 | } 56 | 57 | if (title != null) { 58 | resultString += title + " "; 59 | } 60 | 61 | if (confidence != null) { 62 | resultString += String.format("(%.1f%%) ", confidence * 100.0f); 63 | } 64 | 65 | return resultString.trim(); 66 | } 67 | } 68 | 69 | 70 | WritableArray recognizeImage(String image, Integer inputShape); 71 | 72 | void close(); 73 | } -------------------------------------------------------------------------------- /windows/RNTensorflowLite/RNTensorflowLitePackage.cs: -------------------------------------------------------------------------------- 1 | using ReactNative.Bridge; 2 | using ReactNative.Modules.Core; 3 | using ReactNative.UIManager; 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Tensorflow.Lite.RNTensorflowLite 8 | { 9 | /// 10 | /// Package defining core framework modules (e.g., ). 11 | /// It should be used for modules that require special integration with 12 | /// other framework parts (e.g., with the list of packages to load view 13 | /// managers from). 14 | /// 15 | public class RNTensorflowLitePackage : IReactPackage 16 | { 17 | /// 18 | /// Creates the list of native modules to register with the react 19 | /// instance. 20 | /// 21 | /// The react application context. 22 | /// The list of native modules. 23 | public IReadOnlyList CreateNativeModules(ReactContext reactContext) 24 | { 25 | return new List 26 | { 27 | new RNTensorflowLiteModule(), 28 | }; 29 | } 30 | 31 | /// 32 | /// Creates the list of JavaScript modules to register with the 33 | /// react instance. 34 | /// 35 | /// The list of JavaScript modules. 36 | public IReadOnlyList CreateJavaScriptModulesConfig() 37 | { 38 | return new List(0); 39 | } 40 | 41 | /// 42 | /// Creates the list of view managers that should be registered with 43 | /// the . 44 | /// 45 | /// The react application context. 46 | /// The list of view managers. 47 | public IReadOnlyList CreateViewManagers( 48 | ReactContext reactContext) 49 | { 50 | return new List(0); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /android/src/main/java/com/rntensorflowlite/RNTFLiteImageRecognizerModule.java: -------------------------------------------------------------------------------- 1 | package com.rntensorflowlite.imagerecognition; 2 | 3 | import com.facebook.react.bridge.*; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.List; 8 | 9 | 10 | public class RNTFLiteImageRecognizerModule extends ReactContextBaseJavaModule { 11 | 12 | private Map < Integer, TFLiteImageRecognizer > imageRecognizers = new HashMap < > (); 13 | private final ReactApplicationContext reactContext; 14 | 15 | public RNTFLiteImageRecognizerModule(ReactApplicationContext reactContext) { 16 | super(reactContext); 17 | this.reactContext = reactContext; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "RNTFLiteImageRecognition"; 23 | } 24 | 25 | @ReactMethod 26 | public void createImageRecognizer(ReadableMap data, Promise promise) { 27 | try { 28 | String modelPath = data.getString("model"); 29 | String labelPath = data.getString("labels"); 30 | 31 | TFLiteImageRecognizer ImageRecognizer = TFLiteImageRecognizer.create(this.reactContext, modelPath, labelPath); 32 | imageRecognizers.put(1, ImageRecognizer); 33 | promise.resolve(true); 34 | } catch (Exception e) { 35 | promise.reject(e); 36 | } 37 | } 38 | 39 | @ReactMethod 40 | public void recognize(ReadableMap data, Promise promise) { 41 | try { 42 | String image = data.getString("image"); 43 | Integer inputShape = data.hasKey("inputShape") ? data.getInt("inputShape") : 224; 44 | 45 | TFLiteImageRecognizer ImageRecognizer = imageRecognizers.get(1); 46 | WritableArray result = ImageRecognizer.recognizeImage(image, inputShape); 47 | promise.resolve(result); 48 | } catch (Exception e) { 49 | promise.reject(e); 50 | } 51 | } 52 | 53 | @ReactMethod 54 | public void close(Promise promise) { 55 | try { 56 | imageRecognizers.remove(1); 57 | promise.resolve(true); 58 | } catch (Exception e) { 59 | promise.reject(e); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # react-native-tensorflow-lite 3 | 4 | A react native library for running Tensorflow Lite Image Recognition on Android app. 5 | 6 | 7 | ## Installing 8 | 9 | `$ npm install react-native-tensorflow-lite --save` 10 | 11 | ### Linking 12 | 13 | `$ react-native link react-native-tensorflow-lite` 14 | 15 | ### Converting your model to tflite format 16 | 17 | `Follow this guide: https://www.tensorflow.org/lite/convert/cmdline_examples` 18 | 19 | ### Android 20 | 21 | - Open up `android/app/src/main/java/[...]/MainActivity.java` 22 | - Add `import com.reactlibrary.RNTensorflowLitePackage;` to the imports at the top of the file 23 | - Add `new RNTensorflowLitePackage()` to the list returned by the `getPackages()` method 24 | - Add the following lines to your app's build.gradle(`android/app/build.gradle`): 25 | ``` 26 | android { 27 | aaptOptions { 28 | noCompress 'tflite' 29 | noCompress 'lite' 30 | } 31 | } 32 | ``` 33 | 34 | ## Usage 35 | Place your tflite model file and labels.txt in your app's asset folder. 36 | 37 | ```javascript 38 | import {TFLiteImageRecognition} from 'react-native-tensorflow-lite'; 39 | 40 | class MyImageClassifier extends Component { 41 | 42 | constructor() { 43 | super() 44 | this.state = {} 45 | 46 | try { 47 | // Initialize Tensorflow Lite Image Recognizer 48 | this.classifier = new TFLiteImageRecognition({ 49 | model: "mymodel.tflite", // Your tflite model in assets folder. 50 | labels: "label.txt" // Your label file 51 | }) 52 | 53 | } catch(err) { 54 | alert(err) 55 | } 56 | } 57 | 58 | componentWillMount() { 59 | this.classifyImage("apple.jpg") // Your image path. 60 | } 61 | 62 | async classifyImage(imagePath) { 63 | try { 64 | const results = await this.classifier.recognize({ 65 | image: imagePath, // Your image path. 66 | inputShape: 224, // the input shape of your model. If none given, it will be default to 224. 67 | }) 68 | 69 | const resultObj = { 70 | name: "Name: " + results[0].name, 71 | confidence: "Confidence: " + results[0].confidence, 72 | inference: "Inference: " + results[0].inference + "ms" 73 | }; 74 | this.setState(resultObj) 75 | 76 | } catch(err) { 77 | alert(err) 78 | } 79 | } 80 | 81 | componentWillUnmount() { 82 | this.classifier.close() // Must close the classifier when destroying or unmounting component to release object. 83 | } 84 | 85 | render() { 86 | return ( 87 | 88 | 89 | 90 | {this.state.name} 91 | 92 | 93 | {this.state.confidence} 94 | 95 | 96 | {this.state.inference} 97 | 98 | 99 | 100 | ); 101 | } 102 | } 103 | ``` 104 | 105 | ### Things to note 106 | 107 | - Sometimes, when using the float model the tensorflow lite inference is slower than using the ordinary tensorflow mobile as discussed in this issue https://github.com/tensorflow/tensorflow/issues/21787 108 | 109 | -------------------------------------------------------------------------------- /windows/RNTensorflowLite.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.25123.0 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RNTensorflowLite", "RNTensorflowLite\RNTensorflowLite.csproj", "{F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactNative", "..\node_modules\react-native-windows\ReactWindows\ReactNative\ReactNative.csproj", "{C7673AD5-E3AA-468C-A5FD-FA38154E205C}" 8 | EndProject 9 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ReactNative.Shared", "..\node_modules\react-native-windows\ReactWindows\ReactNative.Shared\ReactNative.Shared.shproj", "{EEA8B852-4D07-48E1-8294-A21AB5909FE5}" 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChakraBridge", "..\node_modules\react-native-windows\ReactWindows\ChakraBridge\ChakraBridge.vcxproj", "{4B72C796-16D5-4E3A-81C0-3E36F531E578}" 12 | EndProject 13 | Global 14 | GlobalSection(SharedMSBuildProjectFiles) = preSolution 15 | ..\node_modules\react-native-windows\ReactWindows\ReactNative.Shared\ReactNative.Shared.projitems*{c7673ad5-e3aa-468c-a5fd-fa38154e205c}*SharedItemsImports = 4 16 | ..\node_modules\react-native-windows\ReactWindows\ReactNative.Shared\ReactNative.Shared.projitems*{eea8b852-4d07-48e1-8294-a21ab5909fe5}*SharedItemsImports = 13 17 | EndGlobalSection 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|ARM = Debug|ARM 20 | Debug|x64 = Debug|x64 21 | Debug|x86 = Debug|x86 22 | Development|ARM = Development|ARM 23 | Development|x64 = Development|x64 24 | Development|x86 = Development|x86 25 | Release|ARM = Release|ARM 26 | Release|x64 = Release|x64 27 | Release|x86 = Release|x86 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Debug|ARM.ActiveCfg = Debug|ARM 31 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Debug|ARM.Build.0 = Debug|ARM 32 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Debug|x64.ActiveCfg = Debug|x64 33 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Debug|x64.Build.0 = Debug|x64 34 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Debug|x86.ActiveCfg = Debug|x86 35 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Debug|x86.Build.0 = Debug|x86 36 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Development|ARM.ActiveCfg = Development|ARM 37 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Development|ARM.Build.0 = Development|ARM 38 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Development|x64.ActiveCfg = Development|x64 39 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Development|x64.Build.0 = Development|x64 40 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Development|x86.ActiveCfg = Development|x86 41 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Development|x86.Build.0 = Development|x86 42 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Release|ARM.ActiveCfg = Release|ARM 43 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Release|ARM.Build.0 = Release|ARM 44 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Release|x64.ActiveCfg = Release|x64 45 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Release|x64.Build.0 = Release|x64 46 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Release|x86.ActiveCfg = Release|x86 47 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E}.Release|x86.Build.0 = Release|x86 48 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Debug|ARM.ActiveCfg = Debug|ARM 49 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Debug|ARM.Build.0 = Debug|ARM 50 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Debug|x64.ActiveCfg = Debug|x64 51 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Debug|x64.Build.0 = Debug|x64 52 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Debug|x86.ActiveCfg = Debug|x86 53 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Debug|x86.Build.0 = Debug|x86 54 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Development|ARM.ActiveCfg = Debug|ARM 55 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Development|ARM.Build.0 = Debug|ARM 56 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Development|x64.ActiveCfg = Debug|x64 57 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Development|x64.Build.0 = Debug|x64 58 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Development|x86.ActiveCfg = Debug|x86 59 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Development|x86.Build.0 = Debug|x86 60 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Release|ARM.ActiveCfg = Release|ARM 61 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Release|ARM.Build.0 = Release|ARM 62 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Release|x64.ActiveCfg = Release|x64 63 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Release|x64.Build.0 = Release|x64 64 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Release|x86.ActiveCfg = Release|x86 65 | {C7673AD5-E3AA-468C-A5FD-FA38154E205C}.Release|x86.Build.0 = Release|x86 66 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Debug|ARM.ActiveCfg = Debug|ARM 67 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Debug|ARM.Build.0 = Debug|ARM 68 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Debug|x64.ActiveCfg = Debug|x64 69 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Debug|x64.Build.0 = Debug|x64 70 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Debug|x86.ActiveCfg = Debug|Win32 71 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Debug|x86.Build.0 = Debug|Win32 72 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Development|ARM.ActiveCfg = Debug|ARM 73 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Development|ARM.Build.0 = Debug|ARM 74 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Development|x64.ActiveCfg = Debug|x64 75 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Development|x64.Build.0 = Debug|x64 76 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Development|x86.ActiveCfg = Debug|Win32 77 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Development|x86.Build.0 = Debug|Win32 78 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Release|ARM.ActiveCfg = Release|ARM 79 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Release|ARM.Build.0 = Release|ARM 80 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Release|x64.ActiveCfg = Release|x64 81 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Release|x64.Build.0 = Release|x64 82 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Release|x86.ActiveCfg = Release|Win32 83 | {4B72C796-16D5-4E3A-81C0-3E36F531E578}.Release|x86.Build.0 = Release|Win32 84 | EndGlobalSection 85 | GlobalSection(SolutionProperties) = preSolution 86 | HideSolutionNode = FALSE 87 | EndGlobalSection 88 | EndGlobal 89 | -------------------------------------------------------------------------------- /windows/RNTensorflowLite/RNTensorflowLite.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x86 7 | {F25F25A0-CC72-11E8-B816-DDE1BDADBC5E} 8 | Library 9 | Properties 10 | Tensorflow.Lite 11 | Tensorflow.Lite 12 | en-US 13 | UAP 14 | 10.0.10586.0 15 | 10.0.10240.0 16 | 14 17 | 512 18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 19 | ..\..\node_modules 20 | 21 | 22 | ..\.. 23 | 24 | 25 | x86 26 | true 27 | bin\x86\Debug\ 28 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 29 | ;2008 30 | full 31 | x86 32 | false 33 | prompt 34 | 35 | 36 | x86 37 | bin\x86\Release\ 38 | TRACE;NETFX_CORE;WINDOWS_UWP 39 | true 40 | ;2008 41 | pdbonly 42 | x86 43 | false 44 | prompt 45 | 46 | 47 | ARM 48 | true 49 | bin\ARM\Debug\ 50 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 51 | ;2008 52 | full 53 | ARM 54 | false 55 | prompt 56 | 57 | 58 | ARM 59 | bin\ARM\Release\ 60 | TRACE;NETFX_CORE;WINDOWS_UWP 61 | true 62 | ;2008 63 | pdbonly 64 | ARM 65 | false 66 | prompt 67 | 68 | 69 | x64 70 | true 71 | bin\x64\Debug\ 72 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 73 | ;2008 74 | full 75 | x64 76 | false 77 | prompt 78 | 79 | 80 | x64 81 | bin\x64\Release\ 82 | TRACE;NETFX_CORE;WINDOWS_UWP 83 | true 84 | ;2008 85 | pdbonly 86 | x64 87 | false 88 | prompt 89 | 90 | 91 | true 92 | bin\x86\Development\ 93 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 94 | ;2008 95 | true 96 | full 97 | x86 98 | false 99 | prompt 100 | MinimumRecommendedRules.ruleset 101 | 102 | 103 | true 104 | bin\ARM\Development\ 105 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 106 | ;2008 107 | true 108 | full 109 | ARM 110 | false 111 | prompt 112 | MinimumRecommendedRules.ruleset 113 | 114 | 115 | true 116 | bin\x64\Development\ 117 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 118 | ;2008 119 | true 120 | full 121 | x64 122 | false 123 | prompt 124 | MinimumRecommendedRules.ruleset 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | {c7673ad5-e3aa-468c-a5fd-fa38154e205c} 139 | ReactNative 140 | 141 | 142 | 143 | 14.0 144 | 145 | 146 | 153 | 154 | -------------------------------------------------------------------------------- /android/src/main/java/com/rntensorflowlite/TFLiteImageRecognizer.java: -------------------------------------------------------------------------------- 1 | package com.rntensorflowlite.imagerecognition; 2 | 3 | import com.facebook.react.bridge.*; 4 | import com.rntensorflowlite.Classifier; 5 | 6 | import android.annotation.SuppressLint; 7 | import android.content.res.AssetFileDescriptor; 8 | import android.content.res.AssetManager; 9 | import android.graphics.Bitmap; 10 | import android.graphics.BitmapFactory; 11 | import android.graphics.Canvas; 12 | import android.graphics.Matrix; 13 | 14 | import org.tensorflow.lite.Interpreter; 15 | 16 | import java.io.InputStream; 17 | import java.io.BufferedReader; 18 | import java.io.FileInputStream; 19 | import java.io.IOException; 20 | import java.io.InputStreamReader; 21 | import java.nio.ByteBuffer; 22 | import java.nio.ByteOrder; 23 | import java.nio.MappedByteBuffer; 24 | import java.nio.channels.FileChannel; 25 | import java.lang.System; 26 | import java.util.*; 27 | 28 | public class TFLiteImageRecognizer implements Classifier { 29 | 30 | private TFLiteImageRecognizer ImageRecognizer; 31 | private ReactContext reactContext; 32 | 33 | private static final int MAX_RESULTS = 3; 34 | private static final int BATCH_SIZE = 1; 35 | private static final int PIXEL_SIZE = 3; 36 | private static final float THRESHOLD = 0.1f; 37 | 38 | long initialTime; 39 | long finalTime; 40 | 41 | private Interpreter classifier; 42 | private int inputShape; 43 | private List labelList; 44 | 45 | 46 | public TFLiteImageRecognizer() {} 47 | 48 | public static TFLiteImageRecognizer create(ReactContext reactContext, String modelPath, String labelPath) throws IOException { 49 | TFLiteImageRecognizer imageRecognizer = new TFLiteImageRecognizer(); 50 | imageRecognizer.reactContext = reactContext; 51 | imageRecognizer.classifier = new Interpreter(imageRecognizer.loadModelFile(reactContext.getAssets(), modelPath)); 52 | imageRecognizer.labelList = imageRecognizer.loadLabelList(reactContext.getAssets(), labelPath); 53 | 54 | return imageRecognizer; 55 | } 56 | 57 | private MappedByteBuffer loadModelFile(AssetManager assetManager, String modelPath) throws IOException { 58 | AssetFileDescriptor fileDescriptor = assetManager.openFd(modelPath); 59 | FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor()); 60 | FileChannel fileChannel = inputStream.getChannel(); 61 | long startOffset = fileDescriptor.getStartOffset(); 62 | long declaredLength = fileDescriptor.getDeclaredLength(); 63 | return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength); 64 | } 65 | 66 | @Override 67 | public WritableArray recognizeImage(final String image, final Integer inputShape) { 68 | this.inputShape = inputShape; 69 | 70 | Bitmap bitmap = convertToBitmap(loadResource(image)); 71 | ByteBuffer byteBuffer = convertBitmapToByteBuffer(bitmap); 72 | float[][] result = new float[1][labelList.size()]; 73 | initialTime = System.currentTimeMillis(); 74 | classifier.run(byteBuffer, result); 75 | finalTime = System.currentTimeMillis() - initialTime; 76 | return getSortedResult(result); 77 | } 78 | 79 | public Boolean hasFilePrefix(String resource) { 80 | if (resource.startsWith("file://")) { 81 | return true; 82 | } 83 | return false; 84 | } 85 | 86 | private byte[] loadResource(String resource) { 87 | try { 88 | InputStream inputStream = this.reactContext.getAssets().open(hasFilePrefix(resource) ? resource.substring(7) : resource); 89 | return inputStreamToByteArray(inputStream); 90 | } catch (Exception e) { 91 | try { 92 | InputStream inputStream = new FileInputStream(hasFilePrefix(resource) ? resource.substring(7) : resource); 93 | return inputStreamToByteArray(inputStream); 94 | } catch (Exception e2) { 95 | return null; 96 | } 97 | } 98 | 99 | } 100 | 101 | private byte[] inputStreamToByteArray(InputStream inputStream) throws IOException { 102 | try { 103 | byte[] b = new byte[inputStream.available()]; 104 | inputStream.read(b); 105 | return b; 106 | } catch (Exception e) { 107 | return null; 108 | } 109 | } 110 | 111 | private Bitmap convertToBitmap(byte[] image) { 112 | BitmapFactory.Options options = new BitmapFactory.Options(); 113 | options.inPreferredConfig = Bitmap.Config.ARGB_8888; 114 | return BitmapFactory.decodeByteArray(image, 0, image.length); 115 | } 116 | 117 | private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmapRaw) { 118 | ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BATCH_SIZE * this.inputShape * this.inputShape * PIXEL_SIZE * 4); 119 | byteBuffer.order(ByteOrder.nativeOrder()); 120 | int[] intValues = new int[this.inputShape * this.inputShape]; 121 | 122 | Bitmap scaledBitmap = Bitmap.createBitmap(this.inputShape, this.inputShape, Bitmap.Config.ARGB_8888); 123 | Matrix matrix = createMatrix(bitmapRaw.getWidth(), bitmapRaw.getHeight(), this.inputShape, this.inputShape); 124 | final Canvas canvas = new Canvas(scaledBitmap); 125 | canvas.drawBitmap(bitmapRaw, matrix, null); 126 | scaledBitmap.getPixels(intValues, 0, scaledBitmap.getWidth(), 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight()); 127 | int pixel = 0; 128 | for (int i = 0; i < this.inputShape; ++i) { 129 | for (int j = 0; j < this.inputShape; ++j) { 130 | final int val = intValues[pixel++]; 131 | byteBuffer.putFloat(((val >> 16) & 0xFF) / 255.0f); 132 | byteBuffer.putFloat(((val >> 8) & 0xFF) / 255.0f); 133 | byteBuffer.putFloat((val & 0xFF) / 255.0f); 134 | } 135 | } 136 | return byteBuffer; 137 | 138 | } 139 | 140 | 141 | private List loadLabelList(AssetManager assetManager, String labelPath) throws IOException { 142 | List labelList = new ArrayList<>(); 143 | BufferedReader reader = new BufferedReader(new InputStreamReader(assetManager.open(labelPath))); 144 | String line; 145 | while ((line = reader.readLine()) != null) { 146 | labelList.add(line); 147 | } 148 | reader.close(); 149 | return labelList; 150 | } 151 | 152 | @SuppressLint("DefaultLocale") 153 | private WritableArray getSortedResult(float[][] labelProbArray) { 154 | 155 | List results = new ArrayList<>(); 156 | 157 | for (int i = 0; i < labelList.size(); ++i) { 158 | float confidence = (labelProbArray[0][i] * 100) / 127.0 f; 159 | if (confidence > THRESHOLD) { 160 | WritableMap entry = new WritableNativeMap(); 161 | entry.putString("id", String.valueOf(i)); 162 | entry.putString("name", labelList.size() > i ? labelList.get(i) : "unknown"); 163 | entry.putDouble("confidence", confidence); 164 | entry.putString("inference", String.valueOf(finalTime)); 165 | results.add(entry); 166 | } 167 | } 168 | 169 | Collections.sort(results, new Comparator () { 170 | @Override 171 | public int compare(ReadableMap first, ReadableMap second) { 172 | return Double.compare(second.getDouble("confidence"), first.getDouble("confidence")); 173 | } 174 | }); 175 | 176 | WritableArray recognitions = new WritableNativeArray(); 177 | int recognitionsSize = Math.min(results.size(), MAX_RESULTS); 178 | for (int i = 0; i < recognitionsSize; ++i) { 179 | recognitions.pushMap(results.get(i)); 180 | } 181 | 182 | return recognitions; 183 | } 184 | 185 | private Matrix createMatrix(int srcWidth, int srcHeight, int dstWidth, int dstHeight) { 186 | Matrix matrix = new Matrix(); 187 | 188 | if (srcWidth != dstWidth || srcHeight != dstHeight) { 189 | float scaleFactorX = dstWidth / (float) srcWidth; 190 | float scaleFactorY = dstHeight / (float) srcHeight; 191 | float scaleFactor = Math.max(scaleFactorX, scaleFactorY); 192 | matrix.postScale(scaleFactor, scaleFactor); 193 | } 194 | 195 | matrix.invert(new Matrix()); 196 | return matrix; 197 | } 198 | 199 | 200 | @Override 201 | public void close() { 202 | this.classifier.close(); 203 | this.classifier = null; 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /ios/RNTensorflowLite.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B3E7B58A1CC2AC0600A0062D /* RNTensorflowLite.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNTensorflowLite.m */; }; 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 /* libRNTensorflowLite.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNTensorflowLite.a; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | B3E7B5881CC2AC0600A0062D /* RNTensorflowLite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNTensorflowLite.h; sourceTree = ""; }; 28 | B3E7B5891CC2AC0600A0062D /* RNTensorflowLite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNTensorflowLite.m; 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 /* libRNTensorflowLite.a */, 46 | ); 47 | name = Products; 48 | sourceTree = ""; 49 | }; 50 | 58B511D21A9E6C8500147676 = { 51 | isa = PBXGroup; 52 | children = ( 53 | B3E7B5881CC2AC0600A0062D /* RNTensorflowLite.h */, 54 | B3E7B5891CC2AC0600A0062D /* RNTensorflowLite.m */, 55 | 134814211AA4EA7D00B7C361 /* Products */, 56 | ); 57 | sourceTree = ""; 58 | }; 59 | /* End PBXGroup section */ 60 | 61 | /* Begin PBXNativeTarget section */ 62 | 58B511DA1A9E6C8500147676 /* RNTensorflowLite */ = { 63 | isa = PBXNativeTarget; 64 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNTensorflowLite" */; 65 | buildPhases = ( 66 | 58B511D71A9E6C8500147676 /* Sources */, 67 | 58B511D81A9E6C8500147676 /* Frameworks */, 68 | 58B511D91A9E6C8500147676 /* CopyFiles */, 69 | ); 70 | buildRules = ( 71 | ); 72 | dependencies = ( 73 | ); 74 | name = RNTensorflowLite; 75 | productName = RCTDataManager; 76 | productReference = 134814201AA4EA6300B7C361 /* libRNTensorflowLite.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 = 0830; 86 | ORGANIZATIONNAME = Facebook; 87 | TargetAttributes = { 88 | 58B511DA1A9E6C8500147676 = { 89 | CreatedOnToolsVersion = 6.1.1; 90 | }; 91 | }; 92 | }; 93 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNTensorflowLite" */; 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 /* RNTensorflowLite */, 106 | ); 107 | }; 108 | /* End PBXProject section */ 109 | 110 | /* Begin PBXSourcesBuildPhase section */ 111 | 58B511D71A9E6C8500147676 /* Sources */ = { 112 | isa = PBXSourcesBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | B3E7B58A1CC2AC0600A0062D /* RNTensorflowLite.m 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_BOOL_CONVERSION = YES; 131 | CLANG_WARN_CONSTANT_CONVERSION = YES; 132 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 133 | CLANG_WARN_EMPTY_BODY = YES; 134 | CLANG_WARN_ENUM_CONVERSION = YES; 135 | CLANG_WARN_INFINITE_RECURSION = YES; 136 | CLANG_WARN_INT_CONVERSION = YES; 137 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 138 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 139 | CLANG_WARN_UNREACHABLE_CODE = YES; 140 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 141 | COPY_PHASE_STRIP = NO; 142 | ENABLE_STRICT_OBJC_MSGSEND = YES; 143 | ENABLE_TESTABILITY = YES; 144 | GCC_C_LANGUAGE_STANDARD = gnu99; 145 | GCC_DYNAMIC_NO_PIC = NO; 146 | GCC_NO_COMMON_BLOCKS = YES; 147 | GCC_OPTIMIZATION_LEVEL = 0; 148 | GCC_PREPROCESSOR_DEFINITIONS = ( 149 | "DEBUG=1", 150 | "$(inherited)", 151 | ); 152 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 153 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 154 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 155 | GCC_WARN_UNDECLARED_SELECTOR = YES; 156 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 157 | GCC_WARN_UNUSED_FUNCTION = YES; 158 | GCC_WARN_UNUSED_VARIABLE = YES; 159 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 160 | MTL_ENABLE_DEBUG_INFO = YES; 161 | ONLY_ACTIVE_ARCH = YES; 162 | SDKROOT = iphoneos; 163 | }; 164 | name = Debug; 165 | }; 166 | 58B511EE1A9E6C8500147676 /* Release */ = { 167 | isa = XCBuildConfiguration; 168 | buildSettings = { 169 | ALWAYS_SEARCH_USER_PATHS = NO; 170 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 171 | CLANG_CXX_LIBRARY = "libc++"; 172 | CLANG_ENABLE_MODULES = YES; 173 | CLANG_ENABLE_OBJC_ARC = YES; 174 | CLANG_WARN_BOOL_CONVERSION = YES; 175 | CLANG_WARN_CONSTANT_CONVERSION = YES; 176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 177 | CLANG_WARN_EMPTY_BODY = YES; 178 | CLANG_WARN_ENUM_CONVERSION = YES; 179 | CLANG_WARN_INFINITE_RECURSION = YES; 180 | CLANG_WARN_INT_CONVERSION = YES; 181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 182 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 183 | CLANG_WARN_UNREACHABLE_CODE = YES; 184 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 185 | COPY_PHASE_STRIP = YES; 186 | ENABLE_NS_ASSERTIONS = NO; 187 | ENABLE_STRICT_OBJC_MSGSEND = YES; 188 | GCC_C_LANGUAGE_STANDARD = gnu99; 189 | GCC_NO_COMMON_BLOCKS = YES; 190 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 191 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 192 | GCC_WARN_UNDECLARED_SELECTOR = YES; 193 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 194 | GCC_WARN_UNUSED_FUNCTION = YES; 195 | GCC_WARN_UNUSED_VARIABLE = YES; 196 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 197 | MTL_ENABLE_DEBUG_INFO = NO; 198 | SDKROOT = iphoneos; 199 | VALIDATE_PRODUCT = YES; 200 | }; 201 | name = Release; 202 | }; 203 | 58B511F01A9E6C8500147676 /* Debug */ = { 204 | isa = XCBuildConfiguration; 205 | buildSettings = { 206 | HEADER_SEARCH_PATHS = ( 207 | "$(inherited)", 208 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 209 | "$(SRCROOT)/../../../React/**", 210 | "$(SRCROOT)/../../react-native/React/**", 211 | ); 212 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 213 | OTHER_LDFLAGS = "-ObjC"; 214 | PRODUCT_NAME = RNTensorflowLite; 215 | SKIP_INSTALL = YES; 216 | }; 217 | name = Debug; 218 | }; 219 | 58B511F11A9E6C8500147676 /* Release */ = { 220 | isa = XCBuildConfiguration; 221 | buildSettings = { 222 | HEADER_SEARCH_PATHS = ( 223 | "$(inherited)", 224 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 225 | "$(SRCROOT)/../../../React/**", 226 | "$(SRCROOT)/../../react-native/React/**", 227 | ); 228 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 229 | OTHER_LDFLAGS = "-ObjC"; 230 | PRODUCT_NAME = RNTensorflowLite; 231 | SKIP_INSTALL = YES; 232 | }; 233 | name = Release; 234 | }; 235 | /* End XCBuildConfiguration section */ 236 | 237 | /* Begin XCConfigurationList section */ 238 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNTensorflowLite" */ = { 239 | isa = XCConfigurationList; 240 | buildConfigurations = ( 241 | 58B511ED1A9E6C8500147676 /* Debug */, 242 | 58B511EE1A9E6C8500147676 /* Release */, 243 | ); 244 | defaultConfigurationIsVisible = 0; 245 | defaultConfigurationName = Release; 246 | }; 247 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNTensorflowLite" */ = { 248 | isa = XCConfigurationList; 249 | buildConfigurations = ( 250 | 58B511F01A9E6C8500147676 /* Debug */, 251 | 58B511F11A9E6C8500147676 /* Release */, 252 | ); 253 | defaultConfigurationIsVisible = 0; 254 | defaultConfigurationName = Release; 255 | }; 256 | /* End XCConfigurationList section */ 257 | }; 258 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 259 | } 260 | --------------------------------------------------------------------------------