react-native-image-stitcher 0.16.1 → 0.16.2

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/CHANGELOG.md CHANGED
@@ -14,6 +14,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
14
  > during 0.x are bumped to a new MINOR (e.g., 0.1 → 0.2), and the
15
15
  > upgrade path is documented in this CHANGELOG.
16
16
 
17
+ ## [0.16.2] — 2026-06-17
18
+
19
+ ### Added — reuse the bundled OpenCV from your host app's native code (Android)
20
+
21
+ A host app's own native (C++/NDK) code can now reuse the **same** custom
22
+ OpenCV this library bundles (4.10.0, arm64-v8a) — **including `cv::Stitcher`**
23
+ — with no second copy of `libopencv_java4.so` in the APK.
24
+
25
+ The Android build now publishes the location of its vendored OpenCV SDK via
26
+ `rootProject.ext.rnisOpenCVDir` (and `rnisOpenCVAndroidSdkDir`). A consumer
27
+ points its `externalNativeBuild` at `-DOpenCV_DIR=${rootProject.ext.rnisOpenCVDir}`,
28
+ calls `find_package(OpenCV)`, and links the shared `opencv_java` (core /
29
+ imgproc / calib3d / … resolved at runtime from the already-shipped `.so`)
30
+ plus the whole-archived static `opencv_stitching` (`cv::Stitcher`). A
31
+ build-verified consumer ships in the example app
32
+ (`example/android/app/src/main/cpp/`).
33
+
34
+ This is additive — no public API or runtime-behaviour change. AGP
35
+ `prefabPublishing` was evaluated and is unworkable for prebuilt OpenCV
36
+ (prefab only exports libraries the module itself builds), so OpenCV's own
37
+ first-class CMake package is used instead. iOS reuse (the vendored
38
+ `opencv2.xcframework`) is unchanged.
39
+
40
+ ### Docs
41
+
42
+ Documentation site refreshed: an easier **Getting started**, a complete
43
+ **`<Camera>` API** reference (every prop, the v0.16 guidance params —
44
+ `rectCrop` / `showPreview` / `panMode` / `panGuidance` / `maxPanDurationMs` /
45
+ `panTooFastThreshold` / `lateralBudgetCm` / `guidanceCopy` — and the
46
+ `stitcher` / `frameSelection` settings-JSON tables), a fully-loaded
47
+ **Complete example**, the v0.16 **Capture result & errors** union, and new
48
+ **Sharing OpenCV** / **Bring your own OpenCV** guides.
49
+
17
50
  ## [0.16.1] — 2026-06-16
18
51
 
19
52
  ### Changed — high-level `cv::Stitcher` is now the default pipeline
package/README.md CHANGED
@@ -29,8 +29,8 @@ Peer dependencies (the host app provides these):
29
29
  "react": ">=18.0.0",
30
30
  "react-native": ">=0.72.0",
31
31
  "react-native-vision-camera": ">=4.7.0",
32
+ "react-native-worklets-core": ">=1.3.0",
32
33
  "react-native-sensors": ">=7.0.0",
33
- "expo-sensors": ">=14.0.0",
34
34
  "react-native-safe-area-context": ">=4.0.0"
35
35
  }
36
36
  ```
@@ -71,50 +71,32 @@ cd android && ./gradlew :app:assembleDebug # Android
71
71
  > See [Orientation support](#orientation-support) for the full story
72
72
  > (landscape *is* supported on iOS if you need it).
73
73
 
74
- The minimum: resolve camera permission, then mount `<Camera>` with an
75
- `onCapture` handler.
74
+ The minimum: mount `<Camera>` with an `onCapture` handler. It fires once
75
+ per capture attempt — gate on `result.ok` before reading the output.
76
76
 
77
77
  ```tsx
78
- import {
79
- Camera,
80
- type CameraCaptureResult,
81
- type CameraError,
82
- } from 'react-native-image-stitcher';
78
+ import { Camera, type CameraCaptureResult } from 'react-native-image-stitcher';
83
79
 
84
80
  export function CaptureScreen() {
85
- const handleCapture = (result: CameraCaptureResult) => {
86
- // `onCapture` fires on success AND failure — gate on `ok` first.
87
- if (!result.ok) {
88
- console.warn('capture failed:', result.error.code, result.error.message);
89
- return;
90
- }
91
- // Non-fatal quality signals (e.g. <70% of frames used). Always present.
92
- if (result.warnings.length > 0) {
93
- console.warn('warnings:', result.warnings.map((w) => w.code));
94
- }
95
- if (result.type === 'photo') {
96
- console.log('Photo:', result.uri, result.width, result.height);
97
- } else {
98
- console.log(
99
- 'Panorama:',
100
- result.uri,
101
- `${result.framesIncluded}/${result.framesRequested} frames`,
102
- `stitched as ${result.stitchModeResolved ?? 'n/a'}`,
103
- );
104
- }
105
- };
106
-
107
81
  return (
108
82
  <Camera
109
- onCapture={handleCapture}
110
- // onError still fires on failure too (an unchanged mirror of the
111
- // ok:false result above).
112
- onError={(err: CameraError) => console.warn(err.code, err.message)}
83
+ onCapture={(result: CameraCaptureResult) => {
84
+ if (!result.ok) {
85
+ console.warn('capture failed:', result.error.code);
86
+ return;
87
+ }
88
+ // result.type is 'photo' or 'panorama'; both carry uri/width/height.
89
+ console.log(result.type, result.uri, result.width, result.height);
90
+ }}
113
91
  />
114
92
  );
115
93
  }
116
94
  ```
117
95
 
96
+ > **Camera permission is the host's job.** The SDK never requests it for
97
+ > you — resolve it (e.g. with vision-camera's `useCameraPermission`)
98
+ > before mounting `<Camera>`.
99
+
118
100
  ### A complete capture screen
119
101
 
120
102
  A realistic screen: requests permission up front, shows a capture
@@ -112,6 +112,40 @@ android {
112
112
  prefab true
113
113
  }
114
114
 
115
+ // ── Host OpenCV reuse: why NOT prefab publishing ─────────────────
116
+ //
117
+ // Goal: let a HOST app's own native (C++/NDK) code reuse the SAME
118
+ // custom OpenCV (4.10.0, arm64-v8a) this AAR already bundles — both
119
+ // libopencv_java4.so (cv::Mat, imgproc, features2d, calib3d, flann,
120
+ // photo, video …) AND cv::Stitcher (which lives in the static
121
+ // archive libopencv_stitching.a, NOT in the fat .so).
122
+ //
123
+ // We evaluated AGP `prefabPublishing` first (the idiomatic AAR way)
124
+ // and it CANNOT carry this OpenCV. Empirically verified: AGP's
125
+ // prefab modules only export libraries the module's own
126
+ // externalNativeBuild PRODUCES (here: just `image_stitcher`). A
127
+ // prebuilt jniLib (.so) or a prebuilt static archive (.a) is not an
128
+ // accepted prefab `libraryName` — the configure fails with
129
+ // `[CXX1404] did not find implicitly required targets`. So neither
130
+ // libopencv_java4.so nor libopencv_stitching.a can ride a prefab.
131
+ //
132
+ // Instead we expose the bundled OpenCV's OWN first-class CMake
133
+ // package — which already defines every module (incl. opencv_stitching
134
+ // as a STATIC IMPORTED target and opencv_java as a SHARED IMPORTED
135
+ // target) — to consumers via a rootProject ext property. A host
136
+ // points its externalNativeBuild at `-DOpenCV_DIR=<that dir>`, does
137
+ // `find_package(OpenCV REQUIRED)`, then links the SHARED `opencv_java`
138
+ // (cv::Mat & friends resolved at runtime from the AAR's already-shipped
139
+ // libopencv_java4.so — NO second copy) plus the whole-archived STATIC
140
+ // `opencv_stitching` (cv::Stitcher, a small private copy since it isn't
141
+ // in the fat .so). This is the idiomatic Android OpenCV-consumption
142
+ // path. See example/android/app for the working consumer.
143
+ //
144
+ // Set unconditionally at configure time so it's readable from the
145
+ // host app module regardless of project evaluation order.
146
+ rootProject.ext.rnisOpenCVAndroidSdkDir = "$opencvSdkDir/native"
147
+ rootProject.ext.rnisOpenCVDir = "$opencvSdkDir/native/jni"
148
+
115
149
  // ── JNI shim build path ─────────────────────────────────────────
116
150
  // Gradle compiles cpp/image_stitcher_jni.cpp into
117
151
  // libimage_stitcher.so for the ABIs filtered above. The shim
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-image-stitcher",
3
- "version": "0.16.1",
3
+ "version": "0.16.2",
4
4
  "description": "Pose-aware panorama capture + stitching for React Native. One <Camera> component, both tap-to-photo and hold-to-pan modes, both AR-backed and IMU-fallback capture paths.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",