ilabs-flir 2.4.8 → 2.4.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/Flir.podspec
CHANGED
|
@@ -60,6 +60,7 @@ public class FlirSdkManager {
|
|
|
60
60
|
private final AtomicBoolean isProcessingFrame = new AtomicBoolean(false);
|
|
61
61
|
private boolean useHalfScale = false;
|
|
62
62
|
private String pendingSnapshotPath = null;
|
|
63
|
+
private volatile List<Palette> cachedSdkPalettes = null;
|
|
63
64
|
|
|
64
65
|
// Listener
|
|
65
66
|
private Listener listener;
|
|
@@ -509,12 +510,24 @@ public class FlirSdkManager {
|
|
|
509
510
|
final String paletteToApply = currentPaletteName;
|
|
510
511
|
final String snapshotPath = pendingSnapshotPath;
|
|
511
512
|
pendingSnapshotPath = null;
|
|
512
|
-
|
|
513
513
|
streamer.withThermalImage(thermalImage -> {
|
|
514
514
|
// 1. Apply Palette
|
|
515
515
|
if (paletteToApply != null) {
|
|
516
516
|
try {
|
|
517
|
-
|
|
517
|
+
List<Palette> sdkPalettes = cachedSdkPalettes;
|
|
518
|
+
if (sdkPalettes == null) {
|
|
519
|
+
synchronized (FlirSdkManager.this) {
|
|
520
|
+
sdkPalettes = cachedSdkPalettes;
|
|
521
|
+
if (sdkPalettes == null) {
|
|
522
|
+
try {
|
|
523
|
+
sdkPalettes = PaletteManager.getDefaultPalettes();
|
|
524
|
+
cachedSdkPalettes = sdkPalettes;
|
|
525
|
+
} catch (Throwable t) {
|
|
526
|
+
Log.e(TAG, "Failed to get default palettes", t);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
518
531
|
|
|
519
532
|
if (paletteToApply.equalsIgnoreCase("Gray") || paletteToApply.equalsIgnoreCase("grayscale")) {
|
|
520
533
|
// User wants Gray - map to WhiteHot which is the SDK's standard grayscale
|
|
@@ -89,6 +89,7 @@ import ThermalSDK
|
|
|
89
89
|
private var stream: FLIRStream?
|
|
90
90
|
private var streamer: FLIRThermalStreamer?
|
|
91
91
|
private var identityMap: [String: FLIRIdentity] = [:]
|
|
92
|
+
private var cachedSdkPalettes: [FLIRPalette]? = nil
|
|
92
93
|
#endif
|
|
93
94
|
|
|
94
95
|
private override init() {
|
|
@@ -753,77 +754,91 @@ extension FlirManager: FLIRStreamDelegate {
|
|
|
753
754
|
_isProcessingFrame = true
|
|
754
755
|
renderQueue.async { [weak self] in
|
|
755
756
|
defer { self?._isProcessingFrame = false }
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
757
|
+
autoreleasepool {
|
|
758
|
+
guard let self = self, self._isStreaming, let streamer = self.streamer else {
|
|
759
|
+
return
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
objc_sync_enter(self.stateLock)
|
|
763
|
+
let currentStreamer = self.streamer
|
|
764
|
+
let streaming = self._isStreaming
|
|
765
|
+
objc_sync_exit(self.stateLock)
|
|
766
|
+
|
|
767
|
+
guard streaming, let streamer = currentStreamer else {
|
|
768
|
+
return
|
|
769
|
+
}
|
|
768
770
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
771
|
+
let paletteToApply = self.currentPaletteName
|
|
772
|
+
let snapshotPath = self.pendingSnapshotPath
|
|
773
|
+
self.pendingSnapshotPath = nil
|
|
772
774
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
streamer.withThermalImage { thermalImage in
|
|
777
|
-
// 1. Apply Palette
|
|
778
|
-
guard let paletteManager = thermalImage.paletteManager,
|
|
779
|
-
let sdkPalettes = paletteManager.getDefaultPalettes() else { return }
|
|
780
|
-
var targetPalette: FLIRPalette? = nil
|
|
775
|
+
do {
|
|
776
|
+
try streamer.update()
|
|
781
777
|
|
|
782
|
-
|
|
783
|
-
//
|
|
784
|
-
|
|
785
|
-
$0.name.lowercased() == "whitehot" || $0.name.lowercased() == "white hot"
|
|
786
|
-
})
|
|
787
|
-
} else {
|
|
788
|
-
targetPalette = sdkPalettes.first(where: { $0.name.lowercased() == paletteToApply.lowercased() })
|
|
778
|
+
streamer.withThermalImage { thermalImage in
|
|
779
|
+
// 1. Apply Palette
|
|
780
|
+
guard let paletteManager = thermalImage.paletteManager else { return }
|
|
789
781
|
|
|
790
|
-
|
|
791
|
-
if
|
|
792
|
-
|
|
793
|
-
|
|
782
|
+
var sdkPalettes = self.cachedSdkPalettes
|
|
783
|
+
if sdkPalettes == nil {
|
|
784
|
+
objc_sync_enter(self.stateLock)
|
|
785
|
+
sdkPalettes = self.cachedSdkPalettes
|
|
786
|
+
if sdkPalettes == nil {
|
|
787
|
+
sdkPalettes = paletteManager.getDefaultPalettes() as? [FLIRPalette]
|
|
788
|
+
self.cachedSdkPalettes = sdkPalettes
|
|
789
|
+
}
|
|
790
|
+
objc_sync_exit(self.stateLock)
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
guard let palettes = sdkPalettes else { return }
|
|
794
|
+
var targetPalette: FLIRPalette? = nil
|
|
795
|
+
|
|
796
|
+
if paletteToApply.lowercased() == "gray" || paletteToApply.lowercased() == "grayscale" {
|
|
797
|
+
// Map Gray to WhiteHot (standard SDK name)
|
|
798
|
+
targetPalette = palettes.first(where: {
|
|
799
|
+
$0.name.lowercased() == "whitehot" || $0.name.lowercased() == "white hot"
|
|
794
800
|
})
|
|
801
|
+
} else {
|
|
802
|
+
targetPalette = palettes.first(where: { $0.name.lowercased() == paletteToApply.lowercased() })
|
|
803
|
+
|
|
804
|
+
// Fallback for Wheel
|
|
805
|
+
if targetPalette == nil && paletteToApply.lowercased() == "wheel" {
|
|
806
|
+
targetPalette = palettes.first(where: {
|
|
807
|
+
$0.name.contains("Wheel") || $0.name.contains("ColorWheel") || $0.name.contains("Rainbow")
|
|
808
|
+
})
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
if let palette = targetPalette {
|
|
813
|
+
thermalImage.palette = palette
|
|
795
814
|
}
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
if let palette = targetPalette {
|
|
799
|
-
thermalImage.palette = palette
|
|
800
|
-
}
|
|
801
815
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
816
|
+
// 2. Save Radiometric Snapshot if requested
|
|
817
|
+
if let path = snapshotPath {
|
|
818
|
+
do {
|
|
819
|
+
try thermalImage.save(as: path)
|
|
820
|
+
NSLog("[FlirManager] Radiometric snapshot saved to: \(path)")
|
|
821
|
+
} catch {
|
|
822
|
+
NSLog("[FlirManager] Failed to save radiometric snapshot: \(error)")
|
|
823
|
+
}
|
|
809
824
|
}
|
|
810
|
-
}
|
|
811
825
|
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
826
|
+
// 3. Generate UIImage for display
|
|
827
|
+
// Grab the image while the thermal image is locked to ensure settings are applied
|
|
828
|
+
if let image = streamer.getImage() {
|
|
829
|
+
self._latestImage = image
|
|
830
|
+
let width = Int(image.size.width)
|
|
831
|
+
let height = Int(image.size.height)
|
|
832
|
+
|
|
833
|
+
DispatchQueue.main.async { [weak self] in
|
|
834
|
+
self?.delegate?.onFrameReceived(image, width: width, height: height)
|
|
835
|
+
}
|
|
821
836
|
}
|
|
822
837
|
}
|
|
838
|
+
} catch {
|
|
839
|
+
NSLog("[FlirManager] Streamer update failed: \(error)")
|
|
840
|
+
return
|
|
823
841
|
}
|
|
824
|
-
} catch {
|
|
825
|
-
NSLog("[FlirManager] Streamer update failed: \(error)")
|
|
826
|
-
return
|
|
827
842
|
}
|
|
828
843
|
}
|
|
829
844
|
}
|
|
@@ -643,23 +643,24 @@ RCT_EXPORT_METHOD(isPreferSdkRotation : (RCTPromiseResolveBlock)
|
|
|
643
643
|
- (void)onFrameReceived:(UIImage *)image
|
|
644
644
|
width:(NSInteger)width
|
|
645
645
|
height:(NSInteger)height {
|
|
646
|
+
@autoreleasepool {
|
|
647
|
+
NSLog(@"[FLIR-TRACE 6️⃣] onFrameReceived in FlirModule - _isCapturing=%d image=%@",
|
|
648
|
+
atomic_load(&_isCapturing), image);
|
|
646
649
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
NSLog(@"[FLIR-TRACE ❌] _isCapturing is false - frame DROPPED");
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
650
|
+
if (!atomic_load(&_isCapturing)) {
|
|
651
|
+
NSLog(@"[FLIR-TRACE ❌] _isCapturing is false - frame DROPPED");
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
654
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
655
|
+
NSLog(@"[FLIR-TRACE 7️⃣] Calling FlirState.updateFrame with image %ldx%ld",
|
|
656
|
+
(long)width, (long)height);
|
|
657
|
+
|
|
658
|
+
// CRITICAL: Update shared state so native preview (FlirPreviewView) receives
|
|
659
|
+
// the texture
|
|
660
|
+
[[FlirState shared] updateFrame:image];
|
|
661
661
|
|
|
662
|
-
|
|
662
|
+
NSLog(@"[FLIR-TRACE 8️⃣] FlirState.updateFrame completed");
|
|
663
|
+
}
|
|
663
664
|
}
|
|
664
665
|
|
|
665
666
|
- (void)onFrameReceivedRaw:(NSData *)data
|
package/ios/Flir/src/FlirState.m
CHANGED
|
@@ -90,12 +90,14 @@ static FlirState *_sharedState = nil;
|
|
|
90
90
|
- (void)updateFrame:(UIImage *)image
|
|
91
91
|
withTemperatureData:(NSArray<NSNumber *> *)tempData {
|
|
92
92
|
dispatch_async(_accessQueue, ^{
|
|
93
|
-
|
|
93
|
+
@autoreleasepool {
|
|
94
|
+
self.latestImage = image;
|
|
94
95
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
if (tempData != nil) {
|
|
97
|
+
self->_temperatureData = [tempData copy];
|
|
98
|
+
self->_imageWidth = (int)image.size.width;
|
|
99
|
+
self->_imageHeight = (int)image.size.height;
|
|
100
|
+
}
|
|
99
101
|
}
|
|
100
102
|
});
|
|
101
103
|
|
|
@@ -110,18 +112,20 @@ static FlirState *_sharedState = nil;
|
|
|
110
112
|
NSLog(@"[FLIR-TRACE 🔟] Dispatching onTextureUpdate callback to main "
|
|
111
113
|
@"queue");
|
|
112
114
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
113
|
-
@
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
115
|
+
@autoreleasepool {
|
|
116
|
+
@try {
|
|
117
|
+
if (self.onTextureUpdate) {
|
|
118
|
+
NSLog(@"[FLIR-TRACE 1️⃣1️⃣] Invoking onTextureUpdate callback with "
|
|
119
|
+
@"image %@",
|
|
120
|
+
image);
|
|
121
|
+
self.onTextureUpdate(image, 7);
|
|
122
|
+
NSLog(@"[FLIR-TRACE 1️⃣2️⃣] onTextureUpdate callback completed");
|
|
123
|
+
} else {
|
|
124
|
+
NSLog(@"[FLIR-TRACE ❌] onTextureUpdate became nil before invoke");
|
|
125
|
+
}
|
|
126
|
+
} @finally {
|
|
127
|
+
atomic_store(&_isTextureBusy, false);
|
|
122
128
|
}
|
|
123
|
-
} @finally {
|
|
124
|
-
atomic_store(&_isTextureBusy, false);
|
|
125
129
|
}
|
|
126
130
|
});
|
|
127
131
|
} else {
|
|
@@ -140,8 +144,10 @@ static FlirState *_sharedState = nil;
|
|
|
140
144
|
double temp = [self getTemperatureAt:centerX y:centerY];
|
|
141
145
|
|
|
142
146
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
143
|
-
|
|
144
|
-
self.onTemperatureUpdate
|
|
147
|
+
@autoreleasepool {
|
|
148
|
+
if (self.onTemperatureUpdate) {
|
|
149
|
+
self.onTemperatureUpdate(temp, centerX, centerY);
|
|
150
|
+
}
|
|
145
151
|
}
|
|
146
152
|
});
|
|
147
153
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ilabs-flir",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.10",
|
|
4
4
|
"description": "FLIR Thermal SDK for React Native - iOS & Android (bundled at compile time via postinstall)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -67,4 +67,4 @@
|
|
|
67
67
|
"sourceDir": "./android/Flir"
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
}
|
|
70
|
+
}
|