react-native-image-stitcher 0.1.2 → 0.1.3
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 +39 -1
- package/README.md +0 -9
- package/android/src/main/cpp/keyframe_gate_jni.cpp +1 -1
- package/android/src/main/java/io/imagestitcher/rn/BatchStitcher.kt +1 -1
- package/android/src/main/java/io/imagestitcher/rn/IncrementalStitcher.kt +2 -2
- package/android/src/main/java/io/imagestitcher/rn/KeyframeGate.kt +1 -1
- package/dist/stitching/stitchFrames.d.ts +1 -1
- package/dist/stitching/stitchFrames.js +1 -1
- package/ios/Package.swift +1 -1
- package/ios/Sources/RNImageStitcher/IncrementalStitcher.swift +4 -4
- package/ios/Sources/RNImageStitcher/KeyframeGate.swift +1 -1
- package/ios/Sources/RNImageStitcher/KeyframeGateBridge.h +1 -1
- package/ios/Sources/RNImageStitcher/KeyframeGateBridge.mm +1 -1
- package/ios/Sources/RNImageStitcher/RNSARSession.swift +1 -1
- package/package.json +1 -1
- package/src/stitching/stitchFrames.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
16
16
|
|
|
17
17
|
## [Unreleased]
|
|
18
18
|
|
|
19
|
+
## [0.1.3] — 2026-05-21
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **Docs / source-comment cleanup.** Removed the leftover
|
|
24
|
+
pre-extraction RetaiLens-monorepo framing from the README — this repo
|
|
25
|
+
is now the canonical, self-contained source of `react-native-image-
|
|
26
|
+
stitcher`, not a downstream subtree of anything. Source-file path
|
|
27
|
+
comments and iOS GCD queue labels now use the canonical
|
|
28
|
+
`io.imagestitcher.*` namespace and `react-native-image-stitcher/`
|
|
29
|
+
repo path instead of the leftover `com.retailens.*` /
|
|
30
|
+
`retailens-capture-sdk/` references that survived the 0.1.0 rename.
|
|
31
|
+
GCD label change affects: `RNSARSession.poseLogQueue`,
|
|
32
|
+
`IncrementalStitcher.workQueue`, `IncrementalStitcher.refineQueue` —
|
|
33
|
+
labels are diagnostic-only (Instruments / crash-report symbolication),
|
|
34
|
+
no public-API or behaviour impact. The CHANGELOG.md migration table
|
|
35
|
+
for [0.1.0] retains the historical `com.retailens.capturesdk` name
|
|
36
|
+
intentionally — it documents the rename that shipped, not the
|
|
37
|
+
current state.
|
|
38
|
+
- **CHANGELOG.** Added compare-links for [0.1.1] and [0.1.2] and fixed
|
|
39
|
+
the [Unreleased] compare base. Annotated the [0.1.0] "Deliberately
|
|
40
|
+
NOT exported" section with a header note explaining that most of
|
|
41
|
+
those entries were promoted to public in [0.1.1] — see the 0.1.1
|
|
42
|
+
*Added* list for the current public surface.
|
|
43
|
+
|
|
19
44
|
## [0.1.2] — 2026-05-20
|
|
20
45
|
|
|
21
46
|
### Added
|
|
@@ -160,6 +185,16 @@ The following are intentionally internal so the public surface stays
|
|
|
160
185
|
small. If you have a real use-case for any of these, please open an
|
|
161
186
|
issue describing it.
|
|
162
187
|
|
|
188
|
+
> [!NOTE]
|
|
189
|
+
> **This list reflects the v0.1.0 surface as shipped.** Most of the
|
|
190
|
+
> entries below — the layer-2 hooks, views, UI components, and
|
|
191
|
+
> incremental-engine primitives — were subsequently promoted to public
|
|
192
|
+
> in [0.1.1]. See the 0.1.1 *Added* section for the current public
|
|
193
|
+
> surface; only a few items below remain internal in later releases
|
|
194
|
+
> (`CameraShutter`, `PanoramaConfirmModal`, `IncrementalStitcherView`,
|
|
195
|
+
> `stitchFrames`, `StitchNotImplementedError`, `runQualityCheck`,
|
|
196
|
+
> `normaliseOrientation`).
|
|
197
|
+
|
|
163
198
|
- `useCapture`, `useDeviceOrientation` — internal hooks `<Camera>`
|
|
164
199
|
composes; expose these only after we have a story for what their
|
|
165
200
|
separate-from-`<Camera>` use-case looks like.
|
|
@@ -206,5 +241,8 @@ Native module names also changed:
|
|
|
206
241
|
- iOS pod: `RetaiLensCaptureSDK` → `RNImageStitcher`
|
|
207
242
|
- iOS xcframework: shipped as `opencv2.xcframework` (linked from `RNImageStitcher.podspec`)
|
|
208
243
|
|
|
209
|
-
[Unreleased]: https://github.com/bhargavkanda/react-native-image-stitcher/compare/v0.1.
|
|
244
|
+
[Unreleased]: https://github.com/bhargavkanda/react-native-image-stitcher/compare/v0.1.3...HEAD
|
|
245
|
+
[0.1.3]: https://github.com/bhargavkanda/react-native-image-stitcher/compare/v0.1.2...v0.1.3
|
|
246
|
+
[0.1.2]: https://github.com/bhargavkanda/react-native-image-stitcher/compare/v0.1.1...v0.1.2
|
|
247
|
+
[0.1.1]: https://github.com/bhargavkanda/react-native-image-stitcher/compare/v0.1.0...v0.1.1
|
|
210
248
|
[0.1.0]: https://github.com/bhargavkanda/react-native-image-stitcher/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -4,15 +4,6 @@
|
|
|
4
4
|
One `<Camera>` component, both tap-to-photo and hold-to-pan modes, both
|
|
5
5
|
AR-backed and IMU-fallback capture paths.
|
|
6
6
|
|
|
7
|
-
> [!NOTE]
|
|
8
|
-
> This package lives in the [RetaiLens monorepo](https://github.com/bhargav-kanda/RetaiLens)
|
|
9
|
-
> under `retailens-capture-sdk/` during development. At publication
|
|
10
|
-
> (see [`2026-05-15-react-native-image-stitcher-publication.md`](https://github.com/bhargav-kanda/RetaiLens/blob/main/docs/site-content/design/2026-05-15-react-native-image-stitcher-publication.md))
|
|
11
|
-
> the public subset is `git subtree split` extracted to a standalone
|
|
12
|
-
> repo at `github.com/bhargavkanda/react-native-image-stitcher` and
|
|
13
|
-
> published to npm. This README describes the **public lib** as it
|
|
14
|
-
> will look post-extraction.
|
|
15
|
-
|
|
16
7
|
## What it does
|
|
17
8
|
|
|
18
9
|
| Feature | Behaviour |
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// keyframe_gate_jni.cpp — JNI bindings exposing the shared C++
|
|
4
4
|
// retailens::KeyframeGate (in ../../../../cpp/) to the Kotlin side
|
|
5
|
-
// (
|
|
5
|
+
// (io.imagestitcher.rn.KeyframeGate).
|
|
6
6
|
//
|
|
7
7
|
// Architecture parity with iOS:
|
|
8
8
|
// iOS uses an Obj-C++ bridge (KeyframeGateBridge.mm) to wrap the
|
|
@@ -50,7 +50,7 @@ class BatchStitcher(reactContext: ReactApplicationContext)
|
|
|
50
50
|
* JNI bridge to our custom-built OpenCV stitcher. Mirrors iOS'
|
|
51
51
|
* OpenCVStitcher.stitchFramePaths so the batch-keyframe flow has
|
|
52
52
|
* parity across platforms. Implementation:
|
|
53
|
-
*
|
|
53
|
+
* react-native-image-stitcher/android/src/main/cpp/image_stitcher_jni.cpp
|
|
54
54
|
*
|
|
55
55
|
* @param framePaths input JPEG paths in capture order (≥2 required)
|
|
56
56
|
* @param outputPath destination JPEG path
|
|
@@ -193,7 +193,7 @@ class IncrementalStitcher(
|
|
|
193
193
|
/// (handleBatchKeyframeFrame above) with the same pose-driven
|
|
194
194
|
/// 40%-new-content algorithm iOS has used since the V16 ship.
|
|
195
195
|
/// Both platforms call into retailens::KeyframeGate (in
|
|
196
|
-
///
|
|
196
|
+
/// react-native-image-stitcher/cpp/keyframe_gate.cpp) — see that file
|
|
197
197
|
/// for the algorithm.
|
|
198
198
|
///
|
|
199
199
|
/// Lifetime: owned for the life of the module. Closed in
|
|
@@ -1159,7 +1159,7 @@ class IncrementalStitcher(
|
|
|
1159
1159
|
// iOS exposes these on the IncrementalStitcherBridge (NOT on the
|
|
1160
1160
|
// ARSession module) so the JS code calls
|
|
1161
1161
|
// getIncrementalNativeModule().getARPlaneStatus()
|
|
1162
|
-
// (see
|
|
1162
|
+
// (see react-native-image-stitcher/src/stitching/incremental.ts:535).
|
|
1163
1163
|
// Both methods delegate to the AR session singleton — same pattern
|
|
1164
1164
|
// as iOS' IncrementalStitcherBridge.swift, where the bridge holds
|
|
1165
1165
|
// the RN @objc surface and the singleton holds the AR algorithm.
|
|
@@ -3,7 +3,7 @@ package io.imagestitcher.rn
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Kotlin facade over the shared C++ KeyframeGate (in
|
|
6
|
-
*
|
|
6
|
+
* react-native-image-stitcher/cpp/keyframe_gate.{hpp,cpp}).
|
|
7
7
|
*
|
|
8
8
|
* Architecture parity with iOS:
|
|
9
9
|
* iOS uses an Obj-C++ bridge (KeyframeGateBridge.mm) to wrap the
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* - iOS: Swift native module that vendors upstream OpenCV's iOS
|
|
6
6
|
* framework and calls `cv::Stitcher::SCANS` mode (designed for
|
|
7
7
|
* translational shelf captures). Lives in
|
|
8
|
-
* `
|
|
8
|
+
* `react-native-image-stitcher/ios/Sources/RNImageStitcher/`.
|
|
9
9
|
* - Android: deferred to Phase 3 — same OpenCV surface, different
|
|
10
10
|
* build (NDK + Gradle). Until that lands, Android calls hit the
|
|
11
11
|
* `StitchNotImplementedError` path below.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - iOS: Swift native module that vendors upstream OpenCV's iOS
|
|
8
8
|
* framework and calls `cv::Stitcher::SCANS` mode (designed for
|
|
9
9
|
* translational shelf captures). Lives in
|
|
10
|
-
* `
|
|
10
|
+
* `react-native-image-stitcher/ios/Sources/RNImageStitcher/`.
|
|
11
11
|
* - Android: deferred to Phase 3 — same OpenCV surface, different
|
|
12
12
|
* build (NDK + Gradle). Until that lands, Android calls hit the
|
|
13
13
|
* `StitchNotImplementedError` path below.
|
package/ios/Package.swift
CHANGED
|
@@ -289,7 +289,7 @@ public final class IncrementalStitcher: NSObject {
|
|
|
289
289
|
/// fix is non-trivial; deferred until pose-driven stitch work
|
|
290
290
|
/// lands (which will rework the queue topology anyway).
|
|
291
291
|
private let workQueue = DispatchQueue(
|
|
292
|
-
label: "
|
|
292
|
+
label: "io.imagestitcher.incremental.stitcher",
|
|
293
293
|
qos: .userInitiated
|
|
294
294
|
)
|
|
295
295
|
|
|
@@ -306,7 +306,7 @@ public final class IncrementalStitcher: NSObject {
|
|
|
306
306
|
/// is out of scope for this MVP — see prompt's "deliberately out
|
|
307
307
|
/// of scope" list).
|
|
308
308
|
private let refineQueue = DispatchQueue(
|
|
309
|
-
label: "
|
|
309
|
+
label: "io.imagestitcher.incremental.refine",
|
|
310
310
|
qos: .utility
|
|
311
311
|
)
|
|
312
312
|
|
|
@@ -1136,7 +1136,7 @@ public final class IncrementalStitcher: NSObject {
|
|
|
1136
1136
|
// Why this matters (RCA from Sentry crashes 2026-05-09
|
|
1137
1137
|
// 21:59-22:03, all 3 .ips traces):
|
|
1138
1138
|
// EXC_BAD_ACCESS at objc_retain+16, frame 1 = closure #1
|
|
1139
|
-
// in finalize+2648, queue =
|
|
1139
|
+
// in finalize+2648, queue = io.imagestitcher.incremental.
|
|
1140
1140
|
// stitcher. +2648 lands inside the os_log call that
|
|
1141
1141
|
// bridges self.batchWarperType → NSString via
|
|
1142
1142
|
// swift_bridgeObjectRetain → objc_retain. The retain
|
|
@@ -1269,7 +1269,7 @@ public final class IncrementalStitcher: NSObject {
|
|
|
1269
1269
|
// under stateLock, closing the visible torn-pointer race.
|
|
1270
1270
|
// Three Sentry traces post-fix4 still showed the same crash
|
|
1271
1271
|
// signature (frame 1 = closure #1 in finalize+N, queue =
|
|
1272
|
-
//
|
|
1272
|
+
// io.imagestitcher.incremental.stitcher), which per the
|
|
1273
1273
|
// systematic-debugging skill (3+ fixes failed on the same
|
|
1274
1274
|
// symptom = wrong architecture) means the workQueue.async
|
|
1275
1275
|
// pattern itself is the problem, not any specific captured
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
//
|
|
5
5
|
// This file used to BE the algorithm (~545 lines of Swift simd math).
|
|
6
6
|
// As of P3-B of the Android-iOS parity work, the algorithm lives in
|
|
7
|
-
//
|
|
7
|
+
// react-native-image-stitcher/cpp/keyframe_gate.{hpp,cpp} and is shared with
|
|
8
8
|
// the Android side via JNI. This Swift class is now a thin facade
|
|
9
9
|
// that:
|
|
10
10
|
//
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
//
|
|
3
3
|
// KeyframeGateBridge.h — Obj-C++ wrapper exposing the shared C++
|
|
4
|
-
// KeyframeGate (in
|
|
4
|
+
// KeyframeGate (in react-native-image-stitcher/cpp/) to Swift.
|
|
5
5
|
//
|
|
6
6
|
// Why this exists:
|
|
7
7
|
// The pose-driven keyframe-selection algorithm is the single most
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
// Single source of truth for the reason-code → string mapping. These
|
|
19
19
|
// strings MUST stay 1:1 with the labels emitted by the original
|
|
20
20
|
// KeyframeGate.swift (and read by the JS telemetry layer in
|
|
21
|
-
//
|
|
21
|
+
// react-native-image-stitcher/src/stitching/incremental.ts). Drift will
|
|
22
22
|
// silently break the JS UI's pill text.
|
|
23
23
|
static NSString *kReasonStringFor(retailens::KeyframeGateDecisionReason r) {
|
|
24
24
|
using R = retailens::KeyframeGateDecisionReason;
|
|
@@ -150,7 +150,7 @@ public final class RNSARSession: NSObject, ARSessionDelegate {
|
|
|
150
150
|
/// recordings. Phase 5 stitching will query by timestamp.
|
|
151
151
|
private var poseLog: [(TimeInterval, RNSARFramePose)] = []
|
|
152
152
|
private let poseLogQueue = DispatchQueue(
|
|
153
|
-
label: "
|
|
153
|
+
label: "io.imagestitcher.arsession.poselog",
|
|
154
154
|
attributes: .concurrent
|
|
155
155
|
)
|
|
156
156
|
private static let MAX_POSE_LOG = 600 // ~10 s @ 60Hz
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-image-stitcher",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
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",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - iOS: Swift native module that vendors upstream OpenCV's iOS
|
|
7
7
|
* framework and calls `cv::Stitcher::SCANS` mode (designed for
|
|
8
8
|
* translational shelf captures). Lives in
|
|
9
|
-
* `
|
|
9
|
+
* `react-native-image-stitcher/ios/Sources/RNImageStitcher/`.
|
|
10
10
|
* - Android: deferred to Phase 3 — same OpenCV surface, different
|
|
11
11
|
* build (NDK + Gradle). Until that lands, Android calls hit the
|
|
12
12
|
* `StitchNotImplementedError` path below.
|