rn-remove-image-bg 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NitroRnRemoveImageBg.podspec +33 -0
- package/README.md +386 -0
- package/android/CMakeLists.txt +28 -0
- package/android/build.gradle +142 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/com/margelo/nitro/rnremoveimagebg/HybridImageBackgroundRemover.kt +189 -0
- package/android/src/main/java/com/margelo/nitro/rnremoveimagebg/NitroRnRemoveImageBgPackage.kt +31 -0
- package/app.plugin.js +12 -0
- package/ios/Bridge.h +8 -0
- package/ios/HybridImageBackgroundRemover.swift +224 -0
- package/ios/NitroRnRemoveImageBgOnLoad.mm +22 -0
- package/lib/ImageProcessing.d.ts +167 -0
- package/lib/ImageProcessing.js +323 -0
- package/lib/ImageProcessing.web.d.ts +80 -0
- package/lib/ImageProcessing.web.js +248 -0
- package/lib/__tests__/cache.test.d.ts +1 -0
- package/lib/__tests__/cache.test.js +87 -0
- package/lib/__tests__/errors.test.d.ts +1 -0
- package/lib/__tests__/errors.test.js +82 -0
- package/lib/cache.d.ts +72 -0
- package/lib/cache.js +228 -0
- package/lib/errors.d.ts +20 -0
- package/lib/errors.js +64 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.js +9 -0
- package/lib/specs/Example.nitro.d.ts +0 -0
- package/lib/specs/Example.nitro.js +2 -0
- package/lib/specs/ImageBackgroundRemover.nitro.d.ts +41 -0
- package/lib/specs/ImageBackgroundRemover.nitro.js +1 -0
- package/nitro.json +17 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/NitroRnRemoveImageBg+autolinking.cmake +81 -0
- package/nitrogen/generated/android/NitroRnRemoveImageBg+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NitroRnRemoveImageBgOnLoad.cpp +44 -0
- package/nitrogen/generated/android/NitroRnRemoveImageBgOnLoad.hpp +25 -0
- package/nitrogen/generated/android/c++/JHybridImageBackgroundRemoverSpec.cpp +72 -0
- package/nitrogen/generated/android/c++/JHybridImageBackgroundRemoverSpec.hpp +65 -0
- package/nitrogen/generated/android/c++/JNativeRemoveBackgroundOptions.hpp +66 -0
- package/nitrogen/generated/android/c++/JOutputFormat.hpp +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rnremoveimagebg/HybridImageBackgroundRemoverSpec.kt +58 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rnremoveimagebg/NativeRemoveBackgroundOptions.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rnremoveimagebg/NitroRnRemoveImageBgOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rnremoveimagebg/OutputFormat.kt +21 -0
- package/nitrogen/generated/ios/NitroRnRemoveImageBg+autolinking.rb +60 -0
- package/nitrogen/generated/ios/NitroRnRemoveImageBg-Swift-Cxx-Bridge.cpp +49 -0
- package/nitrogen/generated/ios/NitroRnRemoveImageBg-Swift-Cxx-Bridge.hpp +111 -0
- package/nitrogen/generated/ios/NitroRnRemoveImageBg-Swift-Cxx-Umbrella.hpp +51 -0
- package/nitrogen/generated/ios/c++/HybridImageBackgroundRemoverSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridImageBackgroundRemoverSpecSwift.hpp +82 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridImageBackgroundRemoverSpec.swift +56 -0
- package/nitrogen/generated/ios/swift/HybridImageBackgroundRemoverSpec_cxx.swift +138 -0
- package/nitrogen/generated/ios/swift/NativeRemoveBackgroundOptions.swift +58 -0
- package/nitrogen/generated/ios/swift/OutputFormat.swift +40 -0
- package/nitrogen/generated/shared/c++/HybridImageBackgroundRemoverSpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridImageBackgroundRemoverSpec.hpp +65 -0
- package/nitrogen/generated/shared/c++/NativeRemoveBackgroundOptions.hpp +84 -0
- package/nitrogen/generated/shared/c++/OutputFormat.hpp +76 -0
- package/package.json +104 -0
- package/react-native.config.js +16 -0
- package/src/ImageProcessing.ts +532 -0
- package/src/ImageProcessing.web.ts +342 -0
- package/src/__tests__/ImageProcessing.test.ts +278 -0
- package/src/__tests__/cache.test.ts +110 -0
- package/src/__tests__/errors.test.ts +117 -0
- package/src/cache.ts +305 -0
- package/src/errors.ts +93 -0
- package/src/index.ts +49 -0
- package/src/specs/Example.nitro.ts +1 -0
- package/src/specs/ImageBackgroundRemover.nitro.ts +49 -0
|
@@ -0,0 +1,33 @@
|
|
|
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 = "NitroRnRemoveImageBg"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported, :visionos => 1.0 }
|
|
14
|
+
s.source = { :git => "https://github.com/a-eid/rn-remove-image-bg.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = [
|
|
17
|
+
# Implementation (Swift)
|
|
18
|
+
"ios/**/*.{swift}",
|
|
19
|
+
# Autolinking/Registration (Objective-C++)
|
|
20
|
+
"ios/**/*.{m,mm}",
|
|
21
|
+
# Implementation (C++ objects)
|
|
22
|
+
"cpp/**/*.{hpp,cpp}",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
s.resources = "ios/Models/*.mlmodel"
|
|
26
|
+
|
|
27
|
+
load 'nitrogen/generated/ios/NitroRnRemoveImageBg+autolinking.rb'
|
|
28
|
+
add_nitrogen_files(s)
|
|
29
|
+
|
|
30
|
+
s.dependency 'React-jsi'
|
|
31
|
+
s.dependency 'React-callinvoker'
|
|
32
|
+
install_modules_dependencies(s)
|
|
33
|
+
end
|
package/README.md
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# rn-remove-image-bg
|
|
2
|
+
|
|
3
|
+
[](https://github.com/a-eid/rn-remove-image-bg)
|
|
4
|
+
[](https://github.com/a-eid/rn-remove-image-bg/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
**Offline background removal for React Native** using native ML models. Works completely on-device with no internet connection required.
|
|
7
|
+
|
|
8
|
+
| Platform | Technology | Min Version |
|
|
9
|
+
|----------|------------|-------------|
|
|
10
|
+
| **iOS** | Vision Framework / CoreML | iOS 16+ |
|
|
11
|
+
| **Android** | ML Kit Subject Segmentation | API 21+ |
|
|
12
|
+
| **Web** | @imgly/background-removal (WASM) | Modern browsers |
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Install from GitHub:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Using npm
|
|
22
|
+
npm install github:a-eid/rn-remove-image-bg react-native-nitro-modules
|
|
23
|
+
|
|
24
|
+
# Using yarn
|
|
25
|
+
yarn add github:a-eid/rn-remove-image-bg react-native-nitro-modules
|
|
26
|
+
|
|
27
|
+
# Using pnpm
|
|
28
|
+
pnpm add github:a-eid/rn-remove-image-bg react-native-nitro-modules
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Or add to your `package.json`:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"rn-remove-image-bg": "github:a-eid/rn-remove-image-bg",
|
|
37
|
+
"react-native-nitro-modules": "0.31.10"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Peer Dependencies
|
|
43
|
+
|
|
44
|
+
This library requires the following peer dependencies for image manipulation:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx expo install expo-file-system expo-image-manipulator
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### iOS Setup
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd ios && pod install
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> **Note:** The library bundles a ~4.5MB CoreML model for iOS 16 support. iOS 17+ uses the built-in Vision Framework.
|
|
57
|
+
|
|
58
|
+
### Android Setup
|
|
59
|
+
|
|
60
|
+
No additional setup required. The ML Kit model (~10MB) downloads automatically on first use.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Quick Start
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { removeBgImage } from 'rn-remove-image-bg'
|
|
68
|
+
|
|
69
|
+
// Remove background from an image
|
|
70
|
+
const resultUri = await removeBgImage('file:///path/to/photo.jpg')
|
|
71
|
+
console.log(resultUri) // file:///path/to/cache/bg_removed_xxx.png
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## API Reference
|
|
77
|
+
|
|
78
|
+
### `removeBgImage(uri, options?)`
|
|
79
|
+
|
|
80
|
+
Remove background from an image using native ML models.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { removeBgImage } from 'rn-remove-image-bg'
|
|
84
|
+
|
|
85
|
+
const result = await removeBgImage('file:///path/to/image.jpg', {
|
|
86
|
+
maxDimension: 2048,
|
|
87
|
+
format: 'PNG',
|
|
88
|
+
quality: 100,
|
|
89
|
+
useCache: true,
|
|
90
|
+
debug: false,
|
|
91
|
+
onProgress: (progress) => console.log(`${progress}%`)
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Parameters
|
|
96
|
+
|
|
97
|
+
| Parameter | Type | Description |
|
|
98
|
+
|-----------|------|-------------|
|
|
99
|
+
| `uri` | `string` | File path or `file://` URI to the source image |
|
|
100
|
+
| `options` | `RemoveBgImageOptions` | Optional processing options |
|
|
101
|
+
|
|
102
|
+
#### Options
|
|
103
|
+
|
|
104
|
+
| Option | Type | Default | Description |
|
|
105
|
+
|--------|------|---------|-------------|
|
|
106
|
+
| `maxDimension` | `number` | `2048` | Max width/height. Larger images are downsampled. |
|
|
107
|
+
| `format` | `'PNG' \| 'WEBP'` | `'PNG'` | Output format. WEBP gives smaller files. |
|
|
108
|
+
| `quality` | `number` | `100` | Quality 0-100 (only affects WEBP). |
|
|
109
|
+
| `useCache` | `boolean` | `true` | Use in-memory cache for repeated calls. |
|
|
110
|
+
| `debug` | `boolean` | `false` | Enable debug logging. |
|
|
111
|
+
| `onProgress` | `(n: number) => void` | — | Progress callback (0-100). |
|
|
112
|
+
|
|
113
|
+
#### Returns
|
|
114
|
+
|
|
115
|
+
`Promise<string>` — A URI suitable for use as an `<Image>` source. The format varies by platform:
|
|
116
|
+
- **iOS/Android**: File path (`file:///path/to/cache/bg_removed_xxx.png`)
|
|
117
|
+
- **Web**: Data URL (`data:image/png;base64,...`)
|
|
118
|
+
|
|
119
|
+
Both formats work directly with React Native's `<Image>` component.
|
|
120
|
+
|
|
121
|
+
#### Example with Options
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { removeBgImage } from 'rn-remove-image-bg'
|
|
125
|
+
|
|
126
|
+
const processImage = async (imageUri: string) => {
|
|
127
|
+
try {
|
|
128
|
+
const result = await removeBgImage(imageUri, {
|
|
129
|
+
maxDimension: 1024, // Faster processing
|
|
130
|
+
format: 'WEBP', // Smaller file size
|
|
131
|
+
quality: 90, // Good quality, smaller size
|
|
132
|
+
onProgress: (p) => {
|
|
133
|
+
console.log(`Processing: ${p}%`)
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
console.log('Background removed:', result)
|
|
138
|
+
return result
|
|
139
|
+
} catch (error) {
|
|
140
|
+
if (error instanceof BackgroundRemovalError) {
|
|
141
|
+
console.error('Error code:', error.code)
|
|
142
|
+
console.error('User message:', error.toUserMessage())
|
|
143
|
+
}
|
|
144
|
+
throw error
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### `compressImage(uri, options?)`
|
|
152
|
+
|
|
153
|
+
Compress and resize an image to a target file size.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { compressImage } from 'rn-remove-image-bg'
|
|
157
|
+
|
|
158
|
+
const compressedUri = await compressImage('file:///path/to/image.jpg', {
|
|
159
|
+
maxSizeKB: 250,
|
|
160
|
+
width: 1024,
|
|
161
|
+
height: 1024,
|
|
162
|
+
quality: 0.85,
|
|
163
|
+
format: 'WEBP'
|
|
164
|
+
})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### Options
|
|
168
|
+
|
|
169
|
+
| Option | Type | Default | Description |
|
|
170
|
+
|--------|------|---------|-------------|
|
|
171
|
+
| `maxSizeKB` | `number` | `250` | Target max file size in KB. |
|
|
172
|
+
| `width` | `number` | `1024` | Target width. |
|
|
173
|
+
| `height` | `number` | `1024` | Target height. |
|
|
174
|
+
| `quality` | `number` | `0.85` | Compression quality (0-1). |
|
|
175
|
+
| `format` | `SaveFormat` | `WEBP` | Output format. |
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### `generateThumbhash(uri, options?)`
|
|
180
|
+
|
|
181
|
+
Generate a compact [thumbhash](https://evanw.github.io/thumbhash/) placeholder for an image.
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { generateThumbhash } from 'rn-remove-image-bg'
|
|
185
|
+
|
|
186
|
+
const hash = await generateThumbhash('file:///path/to/image.jpg', {
|
|
187
|
+
size: 32
|
|
188
|
+
})
|
|
189
|
+
// Returns base64 string like "YTkGJwaRhWWIeHiogohYV4r..."
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### Options
|
|
193
|
+
|
|
194
|
+
| Option | Type | Default | Description |
|
|
195
|
+
|--------|------|---------|-------------|
|
|
196
|
+
| `size` | `number` | `32` | Thumbnail size for hash generation. |
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### Cache Management
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { clearCache, getCacheSize } from 'rn-remove-image-bg'
|
|
204
|
+
|
|
205
|
+
// Get number of cached results
|
|
206
|
+
const size = getCacheSize()
|
|
207
|
+
console.log(`${size} items in cache`)
|
|
208
|
+
|
|
209
|
+
// Clear all cached results
|
|
210
|
+
clearCache()
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Error Handling
|
|
216
|
+
|
|
217
|
+
The library throws `BackgroundRemovalError` with specific error codes:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import { removeBgImage, BackgroundRemovalError } from 'rn-remove-image-bg'
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
await removeBgImage(imageUri)
|
|
224
|
+
} catch (error) {
|
|
225
|
+
if (error instanceof BackgroundRemovalError) {
|
|
226
|
+
switch (error.code) {
|
|
227
|
+
case 'INVALID_PATH':
|
|
228
|
+
console.log('Invalid file path format')
|
|
229
|
+
break
|
|
230
|
+
case 'FILE_NOT_FOUND':
|
|
231
|
+
console.log('Image file not found')
|
|
232
|
+
break
|
|
233
|
+
case 'DECODE_FAILED':
|
|
234
|
+
console.log('Could not decode image')
|
|
235
|
+
break
|
|
236
|
+
case 'ML_PROCESSING_FAILED':
|
|
237
|
+
console.log('ML model failed to process')
|
|
238
|
+
break
|
|
239
|
+
case 'SAVE_FAILED':
|
|
240
|
+
console.log('Could not save result')
|
|
241
|
+
break
|
|
242
|
+
case 'INVALID_OPTIONS':
|
|
243
|
+
console.log('Invalid options provided')
|
|
244
|
+
break
|
|
245
|
+
default:
|
|
246
|
+
console.log('Unknown error')
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Get user-friendly message
|
|
250
|
+
console.log(error.toUserMessage())
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Platform Notes
|
|
258
|
+
|
|
259
|
+
### iOS
|
|
260
|
+
|
|
261
|
+
| iOS Version | Technology | Notes |
|
|
262
|
+
|-------------|------------|-------|
|
|
263
|
+
| iOS 17+ | Vision Framework | Built-in, fastest |
|
|
264
|
+
| iOS 16 | CoreML U2Netp | Bundled ~4.5MB model |
|
|
265
|
+
|
|
266
|
+
- **Output**: PNG (WEBP requested → HEIC on iOS 17+, PNG on iOS 16)
|
|
267
|
+
- **Processing**: Hardware-accelerated via Metal
|
|
268
|
+
- **Memory**: ~2-3x image size during processing
|
|
269
|
+
|
|
270
|
+
### Android
|
|
271
|
+
|
|
272
|
+
- **Technology**: ML Kit Subject Segmentation (beta)
|
|
273
|
+
- **Model**: Downloads ~10MB on first use
|
|
274
|
+
- **Output**: PNG or WEBP (lossy/lossless based on quality)
|
|
275
|
+
- **Requires**: Google Play Services
|
|
276
|
+
|
|
277
|
+
### Web
|
|
278
|
+
|
|
279
|
+
- **Technology**: @imgly/background-removal (WebAssembly + ONNX)
|
|
280
|
+
- **Model**: Downloads ~35MB on first use
|
|
281
|
+
- **Output**: Data URL (`data:image/png;base64,...`) or WEBP
|
|
282
|
+
- **Note**: Works in modern browsers with WebAssembly support
|
|
283
|
+
|
|
284
|
+
> **Return Value Difference**: Web returns data URLs instead of file paths. Both work with `<Image>` components.
|
|
285
|
+
|
|
286
|
+
If you don't need web support, you can tree-shake the `@imgly/background-removal` dependency.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Performance
|
|
291
|
+
|
|
292
|
+
| Metric | iOS | Android |
|
|
293
|
+
|--------|-----|---------|
|
|
294
|
+
| **Processing Time** | 300-1500ms | 500-2000ms |
|
|
295
|
+
| **Peak Memory** | 2-3x image size | 2-3x image size |
|
|
296
|
+
| **First Load** | Instant | ~10MB download |
|
|
297
|
+
|
|
298
|
+
### Optimization Tips
|
|
299
|
+
|
|
300
|
+
1. **Use `maxDimension`** to downsample large images:
|
|
301
|
+
```typescript
|
|
302
|
+
await removeBgImage(uri, { maxDimension: 1024 })
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
2. **Use WEBP format** for smaller output files:
|
|
306
|
+
```typescript
|
|
307
|
+
await removeBgImage(uri, { format: 'WEBP', quality: 85 })
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
3. **Enable caching** for repeated operations:
|
|
311
|
+
```typescript
|
|
312
|
+
await removeBgImage(uri, { useCache: true })
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Best Practices for Quality Results
|
|
318
|
+
|
|
319
|
+
### Photography Tips
|
|
320
|
+
|
|
321
|
+
| Do ✅ | Don't ❌ |
|
|
322
|
+
|------|---------|
|
|
323
|
+
| Even, diffused lighting | Harsh shadows |
|
|
324
|
+
| Plain backgrounds | Busy patterns |
|
|
325
|
+
| Subject 1-2m from backdrop | Subject touching background |
|
|
326
|
+
| Sharp focus on subject | Motion blur |
|
|
327
|
+
| High contrast vs background | Similar colors to background |
|
|
328
|
+
|
|
329
|
+
### What Works Best
|
|
330
|
+
|
|
331
|
+
- ✅ Single, well-defined subjects (people, products, pets)
|
|
332
|
+
- ✅ Solid, opaque objects
|
|
333
|
+
- ✅ Clear edges and outlines
|
|
334
|
+
- ✅ High resolution images (1600x1200+)
|
|
335
|
+
|
|
336
|
+
### Challenging Cases
|
|
337
|
+
|
|
338
|
+
- ⚠️ Transparent/translucent objects (glass, liquids)
|
|
339
|
+
- ⚠️ Very fine details (hair, fur, thin straps)
|
|
340
|
+
- ⚠️ Multiple overlapping subjects
|
|
341
|
+
- ⚠️ Low contrast between subject and background
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Troubleshooting
|
|
346
|
+
|
|
347
|
+
### Poor Results?
|
|
348
|
+
|
|
349
|
+
1. Check lighting conditions
|
|
350
|
+
2. Try a simpler, contrasting background
|
|
351
|
+
3. Ensure subject is in sharp focus
|
|
352
|
+
4. Increase distance between subject and background
|
|
353
|
+
|
|
354
|
+
### Partial Subject Cutoff?
|
|
355
|
+
|
|
356
|
+
1. Ensure clear boundaries around subject
|
|
357
|
+
2. Try repositioning or changing background
|
|
358
|
+
3. Avoid busy patterns near edges
|
|
359
|
+
|
|
360
|
+
### Android Model Not Loading?
|
|
361
|
+
|
|
362
|
+
1. Ensure device has Google Play Services
|
|
363
|
+
2. Check internet connection for first download
|
|
364
|
+
3. Clear app cache and retry
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## TypeScript Support
|
|
369
|
+
|
|
370
|
+
Full TypeScript support with exported types:
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
import type {
|
|
374
|
+
RemoveBgImageOptions,
|
|
375
|
+
CompressImageOptions,
|
|
376
|
+
GenerateThumbhashOptions,
|
|
377
|
+
OutputFormat,
|
|
378
|
+
BackgroundRemovalErrorCode
|
|
379
|
+
} from 'rn-remove-image-bg'
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## License
|
|
385
|
+
|
|
386
|
+
MIT © [Ahmed Eid](https://github.com/a-eid)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
project(NitroRnRemoveImageBg)
|
|
2
|
+
cmake_minimum_required(VERSION 3.9.0)
|
|
3
|
+
|
|
4
|
+
set (PACKAGE_NAME NitroRnRemoveImageBg)
|
|
5
|
+
set (CMAKE_VERBOSE_MAKEFILE ON)
|
|
6
|
+
set (CMAKE_CXX_STANDARD 20)
|
|
7
|
+
|
|
8
|
+
# Define C++ library and add all sources
|
|
9
|
+
add_library(${PACKAGE_NAME} SHARED
|
|
10
|
+
src/main/cpp/cpp-adapter.cpp
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
# Add Nitrogen specs and autolinking - this adds all necessary sources
|
|
14
|
+
include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/NitroRnRemoveImageBg+autolinking.cmake)
|
|
15
|
+
|
|
16
|
+
# Set up local includes
|
|
17
|
+
include_directories(
|
|
18
|
+
"../cpp"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
find_library(LOG_LIB log)
|
|
22
|
+
|
|
23
|
+
# Link all libraries together
|
|
24
|
+
target_link_libraries(
|
|
25
|
+
${PACKAGE_NAME}
|
|
26
|
+
${LOG_LIB}
|
|
27
|
+
android # <-- Android core
|
|
28
|
+
)
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
repositories {
|
|
3
|
+
google()
|
|
4
|
+
mavenCentral()
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
dependencies {
|
|
8
|
+
classpath "com.android.tools.build:gradle:8.13.0"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
def reactNativeArchitectures() {
|
|
13
|
+
def value = rootProject.getProperties().get("reactNativeArchitectures")
|
|
14
|
+
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
def isNewArchitectureEnabled() {
|
|
18
|
+
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
apply plugin: "com.android.library"
|
|
22
|
+
apply plugin: 'org.jetbrains.kotlin.android'
|
|
23
|
+
apply from: '../nitrogen/generated/android/NitroRnRemoveImageBg+autolinking.gradle'
|
|
24
|
+
apply from: "./fix-prefab.gradle"
|
|
25
|
+
|
|
26
|
+
if (isNewArchitectureEnabled()) {
|
|
27
|
+
// apply plugin: "com.facebook.react"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
def getExtOrDefault(name) {
|
|
31
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["NitroRnRemoveImageBg_" + name]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
def getExtOrIntegerDefault(name) {
|
|
35
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["NitroRnRemoveImageBg_" + name]).toInteger()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
android {
|
|
39
|
+
namespace "com.margelo.nitro.rnremoveimagebg"
|
|
40
|
+
|
|
41
|
+
ndkVersion getExtOrDefault("ndkVersion")
|
|
42
|
+
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
|
|
43
|
+
|
|
44
|
+
defaultConfig {
|
|
45
|
+
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
46
|
+
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
47
|
+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
48
|
+
|
|
49
|
+
externalNativeBuild {
|
|
50
|
+
cmake {
|
|
51
|
+
cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
|
|
52
|
+
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
|
53
|
+
abiFilters (*reactNativeArchitectures())
|
|
54
|
+
|
|
55
|
+
buildTypes {
|
|
56
|
+
debug {
|
|
57
|
+
cppFlags "-O1 -g"
|
|
58
|
+
}
|
|
59
|
+
release {
|
|
60
|
+
cppFlags "-O2"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
externalNativeBuild {
|
|
68
|
+
cmake {
|
|
69
|
+
path "CMakeLists.txt"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
packagingOptions {
|
|
74
|
+
excludes = [
|
|
75
|
+
"META-INF",
|
|
76
|
+
"META-INF/**",
|
|
77
|
+
"**/libc++_shared.so",
|
|
78
|
+
"**/libfbjni.so",
|
|
79
|
+
"**/libjsi.so",
|
|
80
|
+
"**/libfolly_json.so",
|
|
81
|
+
"**/libfolly_runtime.so",
|
|
82
|
+
"**/libglog.so",
|
|
83
|
+
"**/libhermes.so",
|
|
84
|
+
"**/libhermes-executor-debug.so",
|
|
85
|
+
"**/libhermes_executor.so",
|
|
86
|
+
"**/libreactnative.so",
|
|
87
|
+
"**/libreactnativejni.so",
|
|
88
|
+
"**/libturbomodulejsijni.so",
|
|
89
|
+
"**/libreact_nativemodule_core.so",
|
|
90
|
+
"**/libjscexecutor.so"
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
buildFeatures {
|
|
95
|
+
buildConfig true
|
|
96
|
+
prefab true
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
buildTypes {
|
|
100
|
+
release {
|
|
101
|
+
minifyEnabled false
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
lintOptions {
|
|
106
|
+
disable "GradleCompatible"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
compileOptions {
|
|
110
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
111
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
sourceSets {
|
|
115
|
+
main {
|
|
116
|
+
if (isNewArchitectureEnabled()) {
|
|
117
|
+
java.srcDirs += [
|
|
118
|
+
// React Codegen files
|
|
119
|
+
"${project.buildDir}/generated/source/codegen/java"
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
repositories {
|
|
127
|
+
mavenCentral()
|
|
128
|
+
google()
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
dependencies {
|
|
133
|
+
// For < 0.71, this will be from the local maven repo
|
|
134
|
+
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
|
|
135
|
+
//noinspection GradleDynamicVersion
|
|
136
|
+
compileOnly "com.facebook.react:react-android:+"
|
|
137
|
+
|
|
138
|
+
// Add a dependency on NitroModules
|
|
139
|
+
implementation project(":react-native-nitro-modules")
|
|
140
|
+
implementation 'com.google.android.gms:play-services-mlkit-subject-segmentation:16.0.0-beta1'
|
|
141
|
+
}
|
|
142
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
tasks.configureEach { task ->
|
|
2
|
+
// Make sure that we generate our prefab publication file only after having built the native library
|
|
3
|
+
// so that not a header publication file, but a full configuration publication will be generated, which
|
|
4
|
+
// will include the .so file
|
|
5
|
+
|
|
6
|
+
def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
|
|
7
|
+
def matcher = task.name =~ prefabConfigurePattern
|
|
8
|
+
if (matcher.matches()) {
|
|
9
|
+
def variantName = matcher[0][1]
|
|
10
|
+
task.outputs.upToDateWhen { false }
|
|
11
|
+
task.dependsOn("externalNativeBuild${variantName}")
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
afterEvaluate {
|
|
16
|
+
def abis = reactNativeArchitectures()
|
|
17
|
+
rootProject.allprojects.each { proj ->
|
|
18
|
+
if (proj === rootProject) return
|
|
19
|
+
|
|
20
|
+
def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config ->
|
|
21
|
+
config.dependencies.any { dep ->
|
|
22
|
+
dep.group == project.group && dep.name == project.name
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (!dependsOnThisLib && proj != project) return
|
|
26
|
+
|
|
27
|
+
if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
|
|
32
|
+
// Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
|
|
33
|
+
// generate a libnameConfig.cmake file that will contain our native library (.so).
|
|
34
|
+
// See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue
|
|
35
|
+
variants.all { variant ->
|
|
36
|
+
def variantName = variant.name
|
|
37
|
+
abis.each { abi ->
|
|
38
|
+
def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
|
|
39
|
+
if (!searchDir.exists()) return
|
|
40
|
+
def matches = []
|
|
41
|
+
searchDir.eachDir { randomDir ->
|
|
42
|
+
def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
|
|
43
|
+
if (prefabFile.exists()) matches << prefabFile
|
|
44
|
+
}
|
|
45
|
+
matches.each { prefabConfig ->
|
|
46
|
+
prefabConfig.setLastModified(System.currentTimeMillis())
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|