2021-05-06 14:11:55 +02:00
---
id: frame-processors-plugins-android
2021-06-28 15:56:49 +02:00
title: Creating Frame Processor Plugins
2021-05-06 14:11:55 +02:00
sidebar_label: Creating Frame Processor Plugins (Android)
---
2023-09-26 11:39:17 +02:00
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
2021-05-06 14:11:55 +02:00
2021-06-28 15:56:49 +02:00
## Creating a Frame Processor Plugin for Android
2021-06-27 12:37:54 +02:00
The Frame Processor Plugin API is built to be as extensible as possible, which allows you to create custom Frame Processor Plugins.
2023-07-21 17:52:30 +02:00
In this guide we will create a custom Face Detector Plugin which can be used from JS.
2021-06-27 12:37:54 +02:00
Android Frame Processor Plugins can be written in either **Java**, **Kotlin** or **C++ (JNI)**.
2022-07-07 14:06:31 +02:00
### Mostly automatic setup
1. Run [Vision Camera Plugin Builder CLI](https://github.com/mateusz1913/vision-camera-plugin-builder)
```sh
2024-01-12 16:11:20 +01:00
npx vision-camera-plugin-builder@latest android
2022-07-07 14:06:31 +02:00
```
:::info
2023-07-21 17:52:30 +02:00
The CLI will ask you for the path to project's Android Manifest file, name of the plugin (e.g. `FaceDetectorFrameProcessorPlugin`), name of the exposed method (e.g. `detectFaces`) and language you want to use for plugin development (Java or Kotlin).
2022-07-07 14:06:31 +02:00
For reference see the [CLI's docs](https://github.com/mateusz1913/vision-camera-plugin-builder#%EF%B8%8F-options).
:::
2. Register the package in MainApplication.java
2023-09-27 12:10:06 +02:00
```java
2022-07-07 14:06:31 +02:00
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
2023-10-03 11:36:55 +02:00
// ...
2023-09-27 12:10:06 +02:00
// highlight-next-line
2023-07-21 17:52:30 +02:00
packages.add(new FaceDetectorFrameProcessorPluginPackage()); // <- add
2022-07-07 14:06:31 +02:00
return packages;
}
```
### Manual setup
2021-06-27 12:37:54 +02:00
<Tabs
defaultValue="java"
values={[
{label: 'Java', value: 'java'},
{label: 'Kotlin', value: 'kotlin'}
]}>
<TabItem value="java">
1. Open your Project in Android Studio
2023-07-21 17:52:30 +02:00
2. Create a Java source file, for the Face Detector Plugin this will be called `FaceDetectorFrameProcessorPlugin.java`.
2021-06-27 12:37:54 +02:00
3. Add the following code:
2023-09-27 12:10:06 +02:00
```java
2023-10-03 11:36:55 +02:00
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
2023-07-22 00:15:11 +02:00
import com.mrousavy.camera.frameprocessor.Frame;
2021-06-27 12:37:54 +02:00
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin;
2024-01-12 16:00:36 +01:00
import com.mrousavy.camera.frameprocessor.VisionCameraProxy;
2021-06-27 12:37:54 +02:00
2023-07-21 17:52:30 +02:00
public class FaceDetectorFrameProcessorPlugin extends FrameProcessorPlugin {
2024-01-12 16:00:36 +01:00
FaceDetectorFrameProcessorPlugin(@NonNull VisionCameraProxy proxy, @Nullable Map<String, Object> options) {}
2023-10-19 10:35:14 +02:00
2023-10-03 11:36:55 +02:00
@Nullable
2021-06-27 12:37:54 +02:00
@Override
2023-10-03 11:36:55 +02:00
public Object callback(@NonNull Frame frame, @Nullable Map<String, Object> arguments) {
// highlight-next-line
2021-06-27 12:37:54 +02:00
// code goes here
return null;
}
}
```
2023-09-01 18:15:28 +02:00
4. **Implement your Frame Processing.** See the [Example Plugin (Java)](https://github.com/mrousavy/react-native-vision-camera/blob/main/package/example/android/app/src/main/java/com/mrousavy/camera/example/ExampleFrameProcessorPlugin.java) for reference.
2023-07-21 17:52:30 +02:00
5. Create a new Java file which registers the Frame Processor Plugin in a React Package, for the Face Detector plugin this file will be called `FaceDetectorFrameProcessorPluginPackage.java`:
2021-06-27 12:37:54 +02:00
2023-09-27 12:10:06 +02:00
```java
2023-10-03 11:36:55 +02:00
import androidx.annotation.NonNull;
2021-06-27 12:37:54 +02:00
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin;
2023-07-22 00:15:11 +02:00
import com.mrousavy.camera.frameprocessor.FrameProcessorPluginRegistry;
2021-06-27 12:37:54 +02:00
2023-07-21 17:52:30 +02:00
public class FaceDetectorFrameProcessorPluginPackage implements ReactPackage {
2023-10-03 11:36:55 +02:00
// highlight-start
2023-10-19 11:34:09 +02:00
static {
2024-01-12 16:00:36 +01:00
FrameProcessorPluginRegistry.addFrameProcessorPlugin("detectFaces", FaceDetectorFrameProcessorPlugin::new);
2023-09-27 12:10:06 +02:00
}
2023-10-03 11:36:55 +02:00
// highlight-end
2023-09-27 12:10:06 +02:00
2021-06-27 12:37:54 +02:00
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
2023-10-03 11:36:55 +02:00
@NonNull
2021-06-27 12:37:54 +02:00
@Override
2023-10-03 11:36:55 +02:00
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
2021-06-27 12:37:54 +02:00
return Collections.emptyList();
}
}
```
2023-09-27 12:15:42 +02:00
:::note
2023-10-19 11:19:47 +02:00
The Frame Processor Plugin will be exposed to JS through the `VisionCameraProxy` object. In this case, it would be `VisionCameraProxy.initFrameProcessorPlugin("detectFaces")`.
2023-09-27 12:15:42 +02:00
:::
2021-09-24 09:15:26 +01:00
6. Register the package in MainApplication.java
2023-09-27 12:10:06 +02:00
```java
2021-09-24 09:15:26 +01:00
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
2023-10-03 11:36:55 +02:00
// ...
2023-09-27 12:10:06 +02:00
// highlight-next-line
2023-07-21 17:52:30 +02:00
packages.add(new FaceDetectorFrameProcessorPluginPackage()); // <- add
2021-09-24 09:15:26 +01:00
return packages;
}
```
2021-06-27 12:37:54 +02:00
</TabItem>
<TabItem value="kotlin">
1. Open your Project in Android Studio
2023-07-21 17:52:30 +02:00
2. Create a Kotlin source file, for the Face Detector Plugin this will be called `FaceDetectorFrameProcessorPlugin.kt`.
2021-06-27 12:37:54 +02:00
3. Add the following code:
2023-09-27 12:10:06 +02:00
```kotlin
2023-07-22 00:15:11 +02:00
import com.mrousavy.camera.frameprocessor.Frame
2021-06-27 12:37:54 +02:00
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin
2024-01-12 16:00:36 +01:00
import com.mrousavy.camera.frameprocessor.VisionCameraProxy
2021-06-27 12:37:54 +02:00
2024-01-12 16:00:36 +01:00
class FaceDetectorFrameProcessorPlugin(proxy: VisionCameraProxy, options: Map<String, Any>?): FrameProcessorPlugin() {
2021-06-27 12:37:54 +02:00
2023-10-19 10:35:14 +02:00
override fun callback(frame: Frame, arguments: Map<String, Any>?): Any? {
2023-10-03 11:36:55 +02:00
// highlight-next-line
2021-06-27 12:37:54 +02:00
// code goes here
return null
}
}
```
2023-10-19 11:19:47 +02:00
4. **Implement your Frame Processing.** See the [Example Plugin (Kotlin)](https://github.com/mrousavy/react-native-vision-camera/blob/main/package/example/android/app/src/main/java/com/mrousavy/camera/example/ExampleKotlinFrameProcessorPlugin.kt) for reference.
2023-07-21 17:52:30 +02:00
5. Create a new Kotlin file which registers the Frame Processor Plugin in a React Package, for the Face Detector plugin this file will be called `FaceDetectorFrameProcessorPluginPackage.kt`:
2021-06-27 12:37:54 +02:00
2023-09-27 12:10:06 +02:00
```kotlin
2021-06-27 12:37:54 +02:00
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin
2023-12-05 14:33:46 -05:00
import com.mrousavy.camera.frameprocessor.FrameProcessorPluginRegistry
2021-06-27 12:37:54 +02:00
2023-07-21 17:52:30 +02:00
class FaceDetectorFrameProcessorPluginPackage : ReactPackage {
2023-10-03 11:36:55 +02:00
// highlight-start
2023-10-19 11:34:09 +02:00
companion object {
init {
2024-01-12 16:00:36 +01:00
FrameProcessorPluginRegistry.addFrameProcessorPlugin("detectFaces") { proxy, options ->
FaceDetectorFrameProcessorPlugin(proxy, options)
2023-10-19 11:34:09 +02:00
}
2023-07-22 00:15:11 +02:00
}
2023-09-27 12:10:06 +02:00
}
2023-10-03 11:36:55 +02:00
// highlight-end
2023-09-27 12:10:06 +02:00
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
2021-06-27 12:37:54 +02:00
return emptyList()
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
}
}
```
2023-09-27 12:15:42 +02:00
:::note
2023-10-19 11:19:47 +02:00
The Frame Processor Plugin will be exposed to JS through the `VisionCameraProxy` object. In this case, it would be `VisionCameraProxy.initFrameProcessorPlugin("detectFaces")`.
2023-09-27 12:15:42 +02:00
:::
2021-09-24 09:15:26 +01:00
6. Register the package in MainApplication.java
2023-09-27 12:10:06 +02:00
```java
2021-09-24 09:15:26 +01:00
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
2023-10-03 11:36:55 +02:00
// ...
2023-09-27 12:10:06 +02:00
// highlight-next-line
2023-07-21 17:52:30 +02:00
packages.add(new FaceDetectorFrameProcessorPluginPackage()); // <- add
2021-09-24 09:15:26 +01:00
return packages;
}
```
2021-06-27 12:37:54 +02:00
</TabItem>
</Tabs>
2021-05-06 14:11:55 +02:00
<br />
#### 🚀 Next section: [Finish creating your Frame Processor Plugin](frame-processors-plugins-final) (or [add iOS support to your Frame Processor Plugin](frame-processors-plugins-ios))