diff --git a/Rekognition/android/build.gradle b/Rekognition/android/build.gradle new file mode 100644 index 0000000..78083f7 --- /dev/null +++ b/Rekognition/android/build.gradle @@ -0,0 +1,33 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:+' + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.3" + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } +} + +repositories { + mavenCentral() +} + +dependencies { + compile project(':aws-sdk-react-native-core') + compile 'com.facebook.react:react-native:+' + compile 'com.amazonaws:aws-android-sdk-core:+' + compile 'com.amazonaws:aws-android-sdk-rekognition:+' +} diff --git a/Rekognition/android/settings.gradle b/Rekognition/android/settings.gradle new file mode 100644 index 0000000..8868319 --- /dev/null +++ b/Rekognition/android/settings.gradle @@ -0,0 +1,4 @@ +include ':aws-sdk-react-native-core' +project(':aws-sdk-react-native-core').projectDir = new File(rootProject.projectDir, '../node_modules/aws-sdk-react-native-core/android') +include ':aws-sdk-react-native-rekognition' +project(':aws-sdk-react-native-rekognition').projectDir = new File(rootProject.projectDir, '../node_modules/aws-sdk-react-native-rekognition/android') diff --git a/Rekognition/android/src/main/AndroidManifest.xml b/Rekognition/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..3cfb1db --- /dev/null +++ b/Rekognition/android/src/main/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + diff --git a/Rekognition/android/src/main/java/com/amazonaws/reactnative/rekognition/AWSRNRekognitionClient.java b/Rekognition/android/src/main/java/com/amazonaws/reactnative/rekognition/AWSRNRekognitionClient.java new file mode 100644 index 0000000..2444c35 --- /dev/null +++ b/Rekognition/android/src/main/java/com/amazonaws/reactnative/rekognition/AWSRNRekognitionClient.java @@ -0,0 +1,245 @@ +// +// Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +package com.amazonaws.reactnative.rekognition; + +import android.util.Log; + +import com.amazonaws.reactnative.core.AWSRNClientConfiguration; +import com.amazonaws.reactnative.core.AWSRNClientMarshaller; +import com.amazonaws.reactnative.core.AWSRNCognitoCredentials; +import com.amazonaws.regions.Region; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.rekognition.*; +import com.amazonaws.services.rekognition.model.*; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableMap; +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import org.json.JSONObject; + +import java.io.IOException; +import java.io.RandomAccessFile; + +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; + +import java.nio.channels.FileChannel; + +public class AWSRNRekognitionClient extends ReactContextBaseJavaModule { + + private AmazonRekognitionClient rekognitionClient; + private Gson gson; + + public AWSRNRekognitionClient(final ReactApplicationContext context) { + super(context); + } + + @Override + public String getName() { + return "AWSRNRekognitionClient"; + } + + @ReactMethod + public void initWithOptions(final ReadableMap options) { + final AWSRNCognitoCredentials credentials = this.getReactApplicationContext().getNativeModule(AWSRNCognitoCredentials.class); + if (credentials.getCredentialsProvider() == null) { + throw new IllegalArgumentException("AWSCognitoCredentials is not initialized"); + } + gson = new GsonBuilder().setFieldNamingStrategy(FieldNamingPolicy.UPPER_CAMEL_CASE).registerTypeAdapter(ByteBuffer.class, AWSRNClientMarshaller.getSerializer()).registerTypeAdapter(ByteBuffer.class, AWSRNClientMarshaller.getDeserializer()).create(); + rekognitionClient = new AmazonRekognitionClient(credentials.getCredentialsProvider(), new AWSRNClientConfiguration().withUserAgent("Rekognition")); + } + + @ReactMethod + public void CompareFaces(final ReadableMap options, final Promise promise) { + try { + final CompareFacesRequest request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), CompareFacesRequest.class); + final CompareFacesResult response = rekognitionClient.compareFaces(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void CreateCollection(final ReadableMap options, final Promise promise) { + try { + final CreateCollectionRequest request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), CreateCollectionRequest.class); + final CreateCollectionResult response = rekognitionClient.createCollection(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void DeleteCollection(final ReadableMap options, final Promise promise) { + try { + final DeleteCollectionRequest request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), DeleteCollectionRequest.class); + final DeleteCollectionResult response = rekognitionClient.deleteCollection(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void DeleteFaces(final ReadableMap options, final Promise promise) { + try { + final DeleteFacesRequest request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), DeleteFacesRequest.class); + final DeleteFacesResult response = rekognitionClient.deleteFaces(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void DetectFaces(final ReadableMap options, final Promise promise) { + try { + final DetectFacesRequest request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), DetectFacesRequest.class); + final DetectFacesResult response = rekognitionClient.detectFaces(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void DetectLabels(final ReadableMap options, final Promise promise) { + try { + final DetectLabelsRequest request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), DetectLabelsRequest.class); + final DetectLabelsResult response = rekognitionClient.detectLabels(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void IndexFaces(final ReadableMap options, final Promise promise) { + try { + final IndexFacesRequest request = new IndexFacesRequest(); + request.setCollectionId(options.getString("CollectionId")); + try { + RandomAccessFile file = new RandomAccessFile(options.getString("Image"), "r"); + FileChannel inChannel = file.getChannel(); + MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); + final Image image = new Image(); + image.withBytes(buffer); + request.setImage(image); + } catch(IOException e) { + Log.w(this.getClass().toString(), e.getMessage()); + } + + final IndexFacesResult response = rekognitionClient.indexFaces(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void ListCollections(final ReadableMap options, final Promise promise) { + try { + final ListCollectionsRequest request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), ListCollectionsRequest.class); + final ListCollectionsResult response = rekognitionClient.listCollections(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void ListFaces(final ReadableMap options, final Promise promise) { + try { + final ListFacesRequest request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), ListFacesRequest.class); + final ListFacesResult response = rekognitionClient.listFaces(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void SearchFaces(final ReadableMap options, final Promise promise) { + try { + final SearchFacesRequest request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), SearchFacesRequest.class); + final SearchFacesResult response = rekognitionClient.searchFaces(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + + @ReactMethod + public void SearchFacesByImage(final ReadableMap options, final Promise promise) { + try { + final SearchFacesByImageRequest request = new SearchFacesByImageRequest(); + request.setCollectionId(options.getString("CollectionId")); + if (options.hasKey("MaxFaces")) { + request.setMaxFaces(options.getInt("MaxFaces")); + } + if (options.hasKey("FaceMatchThreshold")) { + request.setFaceMatchThreshold((float)options.getDouble("FaceMatchThreshold")); + } + try { + RandomAccessFile file = new RandomAccessFile(options.getString("Image"), "r"); + FileChannel inChannel = file.getChannel(); + MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); + final Image image = new Image(); + image.withBytes(buffer); + request.setImage(image); + } catch(IOException e) { + Log.w(this.getClass().toString(), e.getMessage()); + } + + final SearchFacesByImageResult response = rekognitionClient.searchFacesByImage(request); + final WritableMap map = AWSRNClientMarshaller.jsonToReact(new JSONObject(gson.toJson(response))); + promise.resolve(map); + } catch (Exception e) { + promise.reject(e); + return; + } + } + +} diff --git a/Rekognition/android/src/main/java/com/amazonaws/reactnative/rekognition/AWSRNRekognitionPackage.java b/Rekognition/android/src/main/java/com/amazonaws/reactnative/rekognition/AWSRNRekognitionPackage.java new file mode 100644 index 0000000..2a30d44 --- /dev/null +++ b/Rekognition/android/src/main/java/com/amazonaws/reactnative/rekognition/AWSRNRekognitionPackage.java @@ -0,0 +1,52 @@ +// +// Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +package com.amazonaws.reactnative.rekognition; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.JavaScriptModule; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * This is a package to expose AWSRNRekognitionClient.java to AWSRekognitionRekognitionClient.js + * This package is a member of the Integration Testing package for the AWSRekognition SDK for React Native + *

+ * Do not use this package to add any custom classes. + * Please create your own package if necessary. + */ +public class AWSRNRekognitionPackage implements ReactPackage { + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + modules.add(new AWSRNRekognitionClient(reactContext)); + return modules; + } + + @Override + public List> createJSModules() { + return Collections.emptyList(); + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } +} diff --git a/Rekognition/package.json b/Rekognition/package.json new file mode 100644 index 0000000..03e02f6 --- /dev/null +++ b/Rekognition/package.json @@ -0,0 +1,26 @@ +{ + "name": "aws-sdk-react-native-rekognition", + "version": "0.0.1", + "description": "A React Native wrapper for AWS SDK for Rekognition.", + "main": "./src/index.js", + "files": [ + "android/", + "src/" + ], + "repository": { + "type": "git", + "url": "https://github.com/awslabs/aws-sdk-react-native.git" + }, + "keywords": [ + "aws", + "aws mobile", + "react-native", + "react", + "native", + "rekognition" + ], + "author": "Dane Summers", + "license": "Apache-2.0", + "peerDependencies": {}, + "dependencies": {} +} diff --git a/Rekognition/src/AWSRekognition.js b/Rekognition/src/AWSRekognition.js new file mode 100644 index 0000000..58f5955 --- /dev/null +++ b/Rekognition/src/AWSRekognition.js @@ -0,0 +1,159 @@ +// +// Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +import React, { Component } from 'react'; +import { + Platform, + NativeModules, +} from 'react-native'; + +var RekognitionClient = NativeModules.AWSRNRekognitionClient; + +export default class AWSRekognition{ + /* + * Represents a AWSRekognition class + * @constructor + */ + constructor(){ + + } + /* + * Creates a Rekognition client with the given region and registers it. + * @param {string} region - the service region + * @example + * InstanceOfRekognitionClient.initWithOptions({"region":"bucketRegion"}) + */ + initWithOptions(options){ + RekognitionClient.initWithOptions(options); + } + + /* + * Compares a face in the source input image with each face detected in the + * target input image. + * + * @param {map} compareFacesRequest - Input for CompareFaces action. + */ + async CompareFaces(options){ + var returnValue = await RekognitionClient.CompareFaces(options); + return returnValue; + } + + /* + * Creates a collection in an AWS region. You can add faces to the collection + * using the operation. + * + * @param {map} CreateCollectionRequest - Input for CreateCollection action. + */ + async CreateCollection(options){ + var returnValue = await RekognitionClient.CreateCollection(options); + return returnValue; + } + + /* + * Deletes the specified collection. Note that this operation removes all + * faces in the collection. + * + * @param {map} DeleteCollectionRequest - Input for DeleteCollection action. + */ + async DeleteCollection(options){ + var returnValue = await RekognitionClient.DeleteCollection(options); + return returnValue; + } + + /* + * Deletes faces from a collection. You specify a collection ID and an array + * of face IDs to remove from the collection. + * + * @param {map} DeleteFacesRequest - Input for DeleteFaces action. + */ + async DeleteFaces(options){ + var returnValue = await RekognitionClient.DeleteFaces(options); + return returnValue; + } + + /* + * Detects faces within an image (JPEG or PNG) that is provided as input. + * + * @param {map} DetectFacesRequest - Input for DetectFaces action. + */ + async DetectFaces(options){ + var returnValue = await RekognitionClient.DetectFaces(options); + return returnValue; + } + + /* + * Detects instances of real-world labels within an image (JPEG or PNG) + * provided as input. + * + * @param {map} DetectLabelsRequest - Input for CompareFaces action. + */ + async DetectLabels(options){ + var returnValue = await RekognitionClient.DetectLabels(options); + return returnValue; + } + + /* + * Detects faces in the input image and adds them to the specified collection. + * + * @param {map} IndexFacesRequest - Input for IndexFaces action. + */ + async IndexFaces(options){ + var returnValue = await RekognitionClient.IndexFaces(options); + return returnValue; + } + + /* + * Returns list of collection IDs in your account. + * + * @param {map} ListCollectionsRequest - Input for ListCollections action. + */ + async ListCollections(options){ + var returnValue = await RekognitionClient.ListCollections(options); + return returnValue; + } + + /* + * Returns metadata for faces in the specified collection. + * + * @param {map} ListFacesRequest - Input for ListFaces action. + */ + async ListFaces(options){ + var returnValue = await RekognitionClient.ListFaces(options); + return returnValue; + } + + /* + * For a given input face ID, searches the specified collection for matching + * faces. + * + * @param {map} SearchFacesRequest - Input for SearchFaces action. + */ + async SearchFaces(options){ + var returnValue = await RekognitionClient.SearchFaces(options); + return returnValue; + } + + /* + * For a given input image, first detects the largest face in the image, and + * then searches the specified collection for matching faces. + * + * @param {map} SearchFacesByImageRequest - Input for SearchFacesByImage action. + */ + async SearchFacesByImage(options){ + var returnValue = await RekognitionClient.SearchFacesByImage(options); + return returnValue; + } + +} diff --git a/Rekognition/src/index.js b/Rekognition/src/index.js new file mode 100644 index 0000000..756cf63 --- /dev/null +++ b/Rekognition/src/index.js @@ -0,0 +1,20 @@ +// +// Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +import AWSRekognition from "./AWSRekognition"; + +module.exports = { + AWSRekognition: new AWSRekognition() +};