react-native-image-stitcher 0.1.0
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 +96 -0
- package/LICENSE +201 -0
- package/NOTICE +21 -0
- package/README.md +189 -0
- package/RNImageStitcher.podspec +76 -0
- package/android/build.gradle +224 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/cpp/CMakeLists.txt +124 -0
- package/android/src/main/cpp/image_stitcher_jni.cpp +145 -0
- package/android/src/main/cpp/keyframe_gate_jni.cpp +204 -0
- package/android/src/main/java/io/imagestitcher/rn/BatchStitcher.kt +426 -0
- package/android/src/main/java/io/imagestitcher/rn/IncrementalFirstwinsEngine.kt +960 -0
- package/android/src/main/java/io/imagestitcher/rn/IncrementalStitcher.kt +2371 -0
- package/android/src/main/java/io/imagestitcher/rn/KeyframeGate.kt +256 -0
- package/android/src/main/java/io/imagestitcher/rn/QualityChecker.kt +167 -0
- package/android/src/main/java/io/imagestitcher/rn/RNImageStitcherPackage.kt +39 -0
- package/android/src/main/java/io/imagestitcher/rn/RNSARCameraView.kt +558 -0
- package/android/src/main/java/io/imagestitcher/rn/RNSARCameraViewManager.kt +35 -0
- package/android/src/main/java/io/imagestitcher/rn/RNSARSession.kt +784 -0
- package/android/src/main/java/io/imagestitcher/rn/ar/BackgroundRenderer.kt +176 -0
- package/android/src/main/java/io/imagestitcher/rn/ar/ShaderUtil.kt +67 -0
- package/android/src/main/java/io/imagestitcher/rn/ar/YuvImageConverter.kt +201 -0
- package/cpp/ar_frame_pose.h +63 -0
- package/cpp/keyframe_gate.cpp +927 -0
- package/cpp/keyframe_gate.hpp +240 -0
- package/cpp/stitcher.cpp +2207 -0
- package/cpp/stitcher.hpp +275 -0
- package/dist/ar/useARSession.d.ts +102 -0
- package/dist/ar/useARSession.js +133 -0
- package/dist/camera/ARCameraView.d.ts +93 -0
- package/dist/camera/ARCameraView.js +170 -0
- package/dist/camera/Camera.d.ts +134 -0
- package/dist/camera/Camera.js +688 -0
- package/dist/camera/CameraShutter.d.ts +80 -0
- package/dist/camera/CameraShutter.js +237 -0
- package/dist/camera/CameraView.d.ts +65 -0
- package/dist/camera/CameraView.js +117 -0
- package/dist/camera/CaptureControlsBar.d.ts +87 -0
- package/dist/camera/CaptureControlsBar.js +82 -0
- package/dist/camera/CaptureHeader.d.ts +62 -0
- package/dist/camera/CaptureHeader.js +81 -0
- package/dist/camera/CapturePreview.d.ts +70 -0
- package/dist/camera/CapturePreview.js +188 -0
- package/dist/camera/CaptureStatusOverlay.d.ts +75 -0
- package/dist/camera/CaptureStatusOverlay.js +326 -0
- package/dist/camera/CaptureThumbnailStrip.d.ts +87 -0
- package/dist/camera/CaptureThumbnailStrip.js +177 -0
- package/dist/camera/IncrementalPanGuide.d.ts +83 -0
- package/dist/camera/IncrementalPanGuide.js +267 -0
- package/dist/camera/PanoramaBandOverlay.d.ts +107 -0
- package/dist/camera/PanoramaBandOverlay.js +399 -0
- package/dist/camera/PanoramaConfirmModal.d.ts +57 -0
- package/dist/camera/PanoramaConfirmModal.js +128 -0
- package/dist/camera/PanoramaGuidance.d.ts +79 -0
- package/dist/camera/PanoramaGuidance.js +246 -0
- package/dist/camera/PanoramaSettingsModal.d.ts +311 -0
- package/dist/camera/PanoramaSettingsModal.js +611 -0
- package/dist/camera/ViewportCropOverlay.d.ts +46 -0
- package/dist/camera/ViewportCropOverlay.js +67 -0
- package/dist/camera/useCapture.d.ts +111 -0
- package/dist/camera/useCapture.js +160 -0
- package/dist/camera/useDeviceOrientation.d.ts +48 -0
- package/dist/camera/useDeviceOrientation.js +131 -0
- package/dist/camera/useVideoCapture.d.ts +79 -0
- package/dist/camera/useVideoCapture.js +151 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +39 -0
- package/dist/quality/normaliseOrientation.d.ts +36 -0
- package/dist/quality/normaliseOrientation.js +62 -0
- package/dist/quality/runQualityCheck.d.ts +41 -0
- package/dist/quality/runQualityCheck.js +98 -0
- package/dist/sensors/useIMUTranslationGate.d.ts +70 -0
- package/dist/sensors/useIMUTranslationGate.js +235 -0
- package/dist/stitching/IncrementalStitcherView.d.ts +41 -0
- package/dist/stitching/IncrementalStitcherView.js +157 -0
- package/dist/stitching/incremental.d.ts +930 -0
- package/dist/stitching/incremental.js +133 -0
- package/dist/stitching/stitchFrames.d.ts +55 -0
- package/dist/stitching/stitchFrames.js +56 -0
- package/dist/stitching/stitchVideo.d.ts +119 -0
- package/dist/stitching/stitchVideo.js +57 -0
- package/dist/stitching/useIncrementalJSDriver.d.ts +74 -0
- package/dist/stitching/useIncrementalJSDriver.js +199 -0
- package/dist/stitching/useIncrementalStitcher.d.ts +58 -0
- package/dist/stitching/useIncrementalStitcher.js +172 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.js +15 -0
- package/ios/Package.swift +72 -0
- package/ios/Sources/RNImageStitcher/ARCameraViewManager.m +33 -0
- package/ios/Sources/RNImageStitcher/ARCameraViewManager.swift +40 -0
- package/ios/Sources/RNImageStitcher/ARSessionBridge.m +55 -0
- package/ios/Sources/RNImageStitcher/ARSessionBridge.swift +149 -0
- package/ios/Sources/RNImageStitcher/IncrementalStitcher.swift +2727 -0
- package/ios/Sources/RNImageStitcher/IncrementalStitcherBridge.m +85 -0
- package/ios/Sources/RNImageStitcher/IncrementalStitcherBridge.swift +625 -0
- package/ios/Sources/RNImageStitcher/KeyframeGate.swift +328 -0
- package/ios/Sources/RNImageStitcher/KeyframeGateBridge.h +141 -0
- package/ios/Sources/RNImageStitcher/KeyframeGateBridge.mm +278 -0
- package/ios/Sources/RNImageStitcher/OpenCVIncrementalStitcher.h +473 -0
- package/ios/Sources/RNImageStitcher/OpenCVIncrementalStitcher.mm +1326 -0
- package/ios/Sources/RNImageStitcher/OpenCVKeyframeCollector.h +97 -0
- package/ios/Sources/RNImageStitcher/OpenCVKeyframeCollector.mm +296 -0
- package/ios/Sources/RNImageStitcher/OpenCVSlitScanStitcher.h +103 -0
- package/ios/Sources/RNImageStitcher/OpenCVSlitScanStitcher.mm +3285 -0
- package/ios/Sources/RNImageStitcher/OpenCVStitcher.h +238 -0
- package/ios/Sources/RNImageStitcher/OpenCVStitcher.mm +1880 -0
- package/ios/Sources/RNImageStitcher/QualityChecker.swift +252 -0
- package/ios/Sources/RNImageStitcher/QualityCheckerBridge.m +26 -0
- package/ios/Sources/RNImageStitcher/QualityCheckerBridge.swift +72 -0
- package/ios/Sources/RNImageStitcher/RNSARCameraView.swift +114 -0
- package/ios/Sources/RNImageStitcher/RNSARSession.swift +1111 -0
- package/ios/Sources/RNImageStitcher/Stitcher.swift +243 -0
- package/ios/Sources/RNImageStitcher/StitcherBridge.m +28 -0
- package/ios/Sources/RNImageStitcher/StitcherBridge.swift +246 -0
- package/package.json +73 -0
- package/react-native.config.js +34 -0
- package/scripts/opencv-version.txt +1 -0
- package/scripts/postinstall-fetch-binaries.js +286 -0
- package/src/ar/useARSession.ts +210 -0
- package/src/camera/.gitkeep +0 -0
- package/src/camera/ARCameraView.tsx +256 -0
- package/src/camera/Camera.tsx +1053 -0
- package/src/camera/CameraShutter.tsx +292 -0
- package/src/camera/CameraView.tsx +157 -0
- package/src/camera/CaptureControlsBar.tsx +204 -0
- package/src/camera/CaptureHeader.tsx +184 -0
- package/src/camera/CapturePreview.tsx +318 -0
- package/src/camera/CaptureStatusOverlay.tsx +391 -0
- package/src/camera/CaptureThumbnailStrip.tsx +277 -0
- package/src/camera/IncrementalPanGuide.tsx +328 -0
- package/src/camera/PanoramaBandOverlay.tsx +498 -0
- package/src/camera/PanoramaConfirmModal.tsx +206 -0
- package/src/camera/PanoramaGuidance.tsx +327 -0
- package/src/camera/PanoramaSettingsModal.tsx +1357 -0
- package/src/camera/ViewportCropOverlay.tsx +81 -0
- package/src/camera/useCapture.ts +279 -0
- package/src/camera/useDeviceOrientation.ts +140 -0
- package/src/camera/useVideoCapture.ts +236 -0
- package/src/index.ts +53 -0
- package/src/quality/.gitkeep +0 -0
- package/src/quality/normaliseOrientation.ts +79 -0
- package/src/quality/runQualityCheck.ts +131 -0
- package/src/sensors/useIMUTranslationGate.ts +347 -0
- package/src/stitching/.gitkeep +0 -0
- package/src/stitching/IncrementalStitcherView.tsx +198 -0
- package/src/stitching/incremental.ts +1021 -0
- package/src/stitching/stitchFrames.ts +88 -0
- package/src/stitching/stitchVideo.ts +153 -0
- package/src/stitching/useIncrementalJSDriver.ts +273 -0
- package/src/stitching/useIncrementalStitcher.ts +252 -0
- package/src/types.ts +78 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
//
|
|
3
|
+
// ObjC shim that registers RNSARSessionBridge as the
|
|
4
|
+
// "RNSARSession" RN native module — this is what JS
|
|
5
|
+
// imports as `NativeModules.RNSARSession`.
|
|
6
|
+
|
|
7
|
+
#import <React/RCTBridgeModule.h>
|
|
8
|
+
|
|
9
|
+
// REMAP form, NOT EXTERN_MODULE. The Swift singleton in
|
|
10
|
+
// RNSARSession.swift takes the @objc name "RNSARSession"
|
|
11
|
+
// for itself (so ARSessionDelegate dispatch works against a stable
|
|
12
|
+
// ObjC name). Our RN-facing bridge class is `RNSARSessionBridge`.
|
|
13
|
+
// `RCT_EXTERN_MODULE(RNSARSession, ...)` would attach the
|
|
14
|
+
// bridge category to the singleton class — RN would then invoke
|
|
15
|
+
// selectors like `takePhoto:resolver:rejecter:` on the singleton,
|
|
16
|
+
// which doesn't have them, and silently drop the calls.
|
|
17
|
+
//
|
|
18
|
+
// REMAP_MODULE keeps the JS-visible module name as
|
|
19
|
+
// "RNSARSession" but tells RN to instantiate
|
|
20
|
+
// `RNSARSessionBridge` and dispatch methods against THAT
|
|
21
|
+
// class — where takePhoto / startRecording / stopRecording etc.
|
|
22
|
+
// actually live.
|
|
23
|
+
@interface RCT_EXTERN_REMAP_MODULE(RNSARSession, RNSARSessionBridge, NSObject)
|
|
24
|
+
|
|
25
|
+
RCT_EXTERN_METHOD(isSupported:(RCTPromiseResolveBlock)resolver
|
|
26
|
+
rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
27
|
+
|
|
28
|
+
RCT_EXTERN_METHOD(start:(RCTPromiseResolveBlock)resolver
|
|
29
|
+
rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
30
|
+
|
|
31
|
+
RCT_EXTERN_METHOD(stop:(RCTPromiseResolveBlock)resolver
|
|
32
|
+
rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
33
|
+
|
|
34
|
+
RCT_EXTERN_METHOD(getState:(RCTPromiseResolveBlock)resolver
|
|
35
|
+
rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
36
|
+
|
|
37
|
+
RCT_EXTERN_METHOD(snapshotPoseLog:(RCTPromiseResolveBlock)resolver
|
|
38
|
+
rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
39
|
+
|
|
40
|
+
RCT_EXTERN_METHOD(clearPoseLog:(RCTPromiseResolveBlock)resolver
|
|
41
|
+
rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
42
|
+
|
|
43
|
+
// Phase 5 AR-backed photo + video capture
|
|
44
|
+
RCT_EXTERN_METHOD(takePhoto:(NSDictionary *)options
|
|
45
|
+
resolver:(RCTPromiseResolveBlock)resolver
|
|
46
|
+
rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
47
|
+
|
|
48
|
+
RCT_EXTERN_METHOD(startRecording:(NSDictionary *)options
|
|
49
|
+
resolver:(RCTPromiseResolveBlock)resolver
|
|
50
|
+
rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
51
|
+
|
|
52
|
+
RCT_EXTERN_METHOD(stopRecording:(RCTPromiseResolveBlock)resolver
|
|
53
|
+
rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
54
|
+
|
|
55
|
+
@end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
//
|
|
3
|
+
// ARSessionBridge — RN bridge for RNSARSession.
|
|
4
|
+
//
|
|
5
|
+
// JS surface (mirrored on Android via the analogous ARCore bridge):
|
|
6
|
+
//
|
|
7
|
+
// isSupported() → Promise<boolean>
|
|
8
|
+
// start() → Promise<void>
|
|
9
|
+
// stop() → Promise<void>
|
|
10
|
+
// getState() → Promise<{ isRunning, trackingState }>
|
|
11
|
+
// snapshotPoseLog() → Promise<FramePose[]>
|
|
12
|
+
//
|
|
13
|
+
// Phase 5+ APIs (stitchVideoWithPoses) are added on the existing
|
|
14
|
+
// BatchStitcher bridge, not here — keeps each module focused on
|
|
15
|
+
// one ARKit/OpenCV concern.
|
|
16
|
+
|
|
17
|
+
import Foundation
|
|
18
|
+
import React
|
|
19
|
+
|
|
20
|
+
@objc(RNSARSessionBridge)
|
|
21
|
+
public final class RNSARSessionBridge: NSObject {
|
|
22
|
+
|
|
23
|
+
@objc public static func requiresMainQueueSetup() -> Bool {
|
|
24
|
+
// ARSession.start() must be called on the main thread —
|
|
25
|
+
// ARKit needs to attach to the active CVDisplayLink.
|
|
26
|
+
return true
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@objc(isSupported:rejecter:)
|
|
30
|
+
public func isSupported(
|
|
31
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
32
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
33
|
+
) {
|
|
34
|
+
resolver(RNSARSession.isSupported)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@objc(start:rejecter:)
|
|
38
|
+
public func start(
|
|
39
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
40
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
41
|
+
) {
|
|
42
|
+
DispatchQueue.main.async {
|
|
43
|
+
RNSARSession.shared.start()
|
|
44
|
+
resolver(nil)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@objc(stop:rejecter:)
|
|
49
|
+
public func stop(
|
|
50
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
51
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
52
|
+
) {
|
|
53
|
+
DispatchQueue.main.async {
|
|
54
|
+
RNSARSession.shared.stop()
|
|
55
|
+
resolver(nil)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@objc(getState:rejecter:)
|
|
60
|
+
public func getState(
|
|
61
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
62
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
63
|
+
) {
|
|
64
|
+
let s = RNSARSession.shared
|
|
65
|
+
resolver([
|
|
66
|
+
"isRunning": s.isRunning,
|
|
67
|
+
"trackingState": s.currentTrackingState.rawValue,
|
|
68
|
+
])
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@objc(snapshotPoseLog:rejecter:)
|
|
72
|
+
public func snapshotPoseLog(
|
|
73
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
74
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
75
|
+
) {
|
|
76
|
+
let poses = RNSARSession.shared.snapshotPoseLog()
|
|
77
|
+
resolver(poses.map { $0.asDictionary() })
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@objc(clearPoseLog:rejecter:)
|
|
81
|
+
public func clearPoseLog(
|
|
82
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
83
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
84
|
+
) {
|
|
85
|
+
RNSARSession.shared.clearPoseLog()
|
|
86
|
+
resolver(nil)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// MARK: - Phase 5: AR-backed photo + video capture
|
|
90
|
+
|
|
91
|
+
/// `options` keys: `path` (required), `quality` (optional, 0-100,
|
|
92
|
+
/// default 90). Resolves with `{ path, width, height, isMirrored,
|
|
93
|
+
/// isRawPhoto }` matching vision-camera's PhotoFile shape.
|
|
94
|
+
@objc(takePhoto:resolver:rejecter:)
|
|
95
|
+
public func takePhoto(
|
|
96
|
+
options: NSDictionary,
|
|
97
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
98
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
99
|
+
) {
|
|
100
|
+
let path = (options["path"] as? String) ?? ""
|
|
101
|
+
let quality = (options["quality"] as? Int) ?? 90
|
|
102
|
+
RNSARSession.shared.takePhoto(
|
|
103
|
+
toPath: path,
|
|
104
|
+
quality: quality
|
|
105
|
+
) { result, error in
|
|
106
|
+
if let error = error {
|
|
107
|
+
rejecter("ar-photo-failed", error.localizedDescription, error)
|
|
108
|
+
} else {
|
|
109
|
+
resolver(result)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/// `options` keys: `path` (optional, native generates one in
|
|
115
|
+
/// NSTemporaryDirectory when omitted). Resolves with `{ path }`
|
|
116
|
+
/// once recording is set up (frames begin flowing automatically
|
|
117
|
+
/// from the ARSession delegate).
|
|
118
|
+
@objc(startRecording:resolver:rejecter:)
|
|
119
|
+
public func startRecording(
|
|
120
|
+
options: NSDictionary,
|
|
121
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
122
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
123
|
+
) {
|
|
124
|
+
let path = (options["path"] as? String) ?? ""
|
|
125
|
+
RNSARSession.shared.startRecording(toPath: path) { resolvedPath, error in
|
|
126
|
+
if let error = error {
|
|
127
|
+
rejecter("ar-recording-failed", error.localizedDescription, error)
|
|
128
|
+
} else {
|
|
129
|
+
resolver(["path": resolvedPath ?? ""])
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/// Resolves with `{ path, duration, size, width, height }`
|
|
135
|
+
/// matching vision-camera's VideoFile shape.
|
|
136
|
+
@objc(stopRecording:rejecter:)
|
|
137
|
+
public func stopRecording(
|
|
138
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
139
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
140
|
+
) {
|
|
141
|
+
RNSARSession.shared.stopRecording { result, error in
|
|
142
|
+
if let error = error {
|
|
143
|
+
rejecter("ar-stop-failed", error.localizedDescription, error)
|
|
144
|
+
} else {
|
|
145
|
+
resolver(result)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|