ilabs-flir 2.4.3 → 2.4.5
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/android/Flir/src/main/java/flir/android/FlirManager.kt +16 -3
- package/android/Flir/src/main/java/flir/android/FlirModule.kt +4 -3
- package/android/Flir/src/main/java/flir/android/FlirSdkManager.java +18 -16
- package/ios/Flir/src/FlirManager.swift +21 -3
- package/ios/Flir/src/FlirModule.m +6 -5
- package/package.json +1 -1
|
@@ -250,10 +250,23 @@ object FlirManager {
|
|
|
250
250
|
return if (temp != null && !temp.isNaN()) temp else null
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
fun getTemperatureAtNormalized(nx: Double, ny: Double): Double? {
|
|
253
|
+
fun getTemperatureAtNormalized(nx: Double, ny: Double, rotation: Int = -90): Double? {
|
|
254
254
|
val bitmap = latestBitmap ?: return null
|
|
255
|
-
|
|
256
|
-
|
|
255
|
+
|
|
256
|
+
// Map UI normalized (0..1) to Raw sensor normalized (0..1) based on display rotation
|
|
257
|
+
val rawCoords = when (rotation) {
|
|
258
|
+
0 -> Pair(nx, ny)
|
|
259
|
+
90, -270 -> Pair(ny, 1.0 - nx)
|
|
260
|
+
180, -180 -> Pair(1.0 - nx, 1.0 - ny)
|
|
261
|
+
270, -90 -> Pair(1.0 - ny, nx)
|
|
262
|
+
else -> Pair(1.0 - ny, nx) // Default to -90 for backward compatibility
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
val rawX = rawCoords.first
|
|
266
|
+
val rawY = rawCoords.second
|
|
267
|
+
|
|
268
|
+
val px = (rawX * bitmap.width).toInt().coerceIn(0, bitmap.width - 1)
|
|
269
|
+
val py = (rawY * bitmap.height).toInt().coerceIn(0, bitmap.height - 1)
|
|
257
270
|
return getTemperatureAt(px, py)
|
|
258
271
|
}
|
|
259
272
|
|
|
@@ -69,9 +69,9 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
@ReactMethod
|
|
72
|
-
fun getTemperatureAtNormalized(nx: Double, ny: Double, promise: Promise?) {
|
|
72
|
+
fun getTemperatureAtNormalized(nx: Double, ny: Double, rotation: Int, promise: Promise?) {
|
|
73
73
|
try {
|
|
74
|
-
val temp = FlirManager.getTemperatureAtNormalized(nx, ny)
|
|
74
|
+
val temp = FlirManager.getTemperatureAtNormalized(nx, ny, rotation)
|
|
75
75
|
if (temp != null) promise?.resolve(temp) else promise?.resolve(null)
|
|
76
76
|
} catch (e: Exception) {
|
|
77
77
|
promise?.reject("ERR_FLIR_TEMP_NORM", e)
|
|
@@ -340,7 +340,8 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
340
340
|
@ReactMethod
|
|
341
341
|
fun resumeFlirAfterPreview(promise: Promise?) {
|
|
342
342
|
try {
|
|
343
|
-
|
|
343
|
+
// Respect the gate - do not open it blindly on resume
|
|
344
|
+
FlirManager.startDiscovery()
|
|
344
345
|
promise?.resolve(true)
|
|
345
346
|
} catch (e: Exception) {
|
|
346
347
|
promise?.reject("ERR_RESUME_FLIR", e)
|
|
@@ -48,7 +48,7 @@ public class FlirSdkManager {
|
|
|
48
48
|
private final Executor executor = Executors.newSingleThreadExecutor();
|
|
49
49
|
|
|
50
50
|
// State
|
|
51
|
-
private
|
|
51
|
+
private final AtomicBoolean isInitialized = new AtomicBoolean(false);
|
|
52
52
|
private boolean isScanning = false;
|
|
53
53
|
private Camera camera;
|
|
54
54
|
private ThermalStreamer streamer;
|
|
@@ -103,32 +103,34 @@ public class FlirSdkManager {
|
|
|
103
103
|
// ==================== INITIALIZE ====================
|
|
104
104
|
|
|
105
105
|
public void initialize() {
|
|
106
|
-
if (isInitialized)
|
|
107
|
-
|
|
108
|
-
try {
|
|
109
|
-
ThermalSdkAndroid.init(context);
|
|
106
|
+
if (isInitialized.compareAndSet(false, true)) {
|
|
107
|
+
Log.d(TAG, "Initializing FLIR SDK (async)...");
|
|
110
108
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
109
|
+
executor.execute(() -> {
|
|
110
|
+
try {
|
|
111
|
+
ThermalSdkAndroid.init(context);
|
|
112
|
+
|
|
113
|
+
// Small delay to ensure JNI linkage is stable
|
|
114
|
+
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
|
|
115
|
+
|
|
116
|
+
Log.d(TAG, "FLIR SDK initialized successfully on background thread. Arch: " + System.getProperty("os.arch"));
|
|
117
|
+
} catch (Throwable t) {
|
|
118
|
+
Log.e(TAG, "Failed to initialize FLIR SDK", t);
|
|
119
|
+
isInitialized.set(false);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
public boolean isInitialized() {
|
|
124
|
-
return isInitialized;
|
|
126
|
+
return isInitialized.get();
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
// ==================== DISCOVERY ====================
|
|
128
130
|
|
|
129
131
|
public void scan() {
|
|
130
132
|
executor.execute(() -> {
|
|
131
|
-
if (!isInitialized) {
|
|
133
|
+
if (!isInitialized.get()) {
|
|
132
134
|
notifyError("SDK not initialized");
|
|
133
135
|
return;
|
|
134
136
|
}
|
|
@@ -468,7 +468,7 @@ import ThermalSDK
|
|
|
468
468
|
#endif
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
-
@objc public func getTemperatureAtNormalized(_ nx: Double, y: Double) -> Double {
|
|
471
|
+
@objc public func getTemperatureAtNormalized(_ nx: Double, y: Double, rotation: Int) -> Double {
|
|
472
472
|
#if FLIR_ENABLED
|
|
473
473
|
guard let streamer = streamer, _isStreaming else { return Double.nan }
|
|
474
474
|
|
|
@@ -477,9 +477,27 @@ import ThermalSDK
|
|
|
477
477
|
let w = Double(thermalImage.getWidth())
|
|
478
478
|
let h = Double(thermalImage.getHeight())
|
|
479
479
|
|
|
480
|
+
// Map UI normalized (0..1) to Raw sensor normalized (0..1) based on display rotation
|
|
481
|
+
var rawX = nx
|
|
482
|
+
var rawY = y
|
|
483
|
+
|
|
484
|
+
switch rotation {
|
|
485
|
+
case 90, -270:
|
|
486
|
+
rawX = y
|
|
487
|
+
rawY = 1.0 - nx
|
|
488
|
+
case 180, -180:
|
|
489
|
+
rawX = 1.0 - nx
|
|
490
|
+
rawY = 1.0 - y
|
|
491
|
+
case 270, -90:
|
|
492
|
+
rawX = 1.0 - y
|
|
493
|
+
rawY = nx
|
|
494
|
+
default:
|
|
495
|
+
break // 0 deg or default
|
|
496
|
+
}
|
|
497
|
+
|
|
480
498
|
// Map normalized (0.0 - 1.0) to actual sensor pixels
|
|
481
|
-
let cx = max(0, min(Int(w) - 1, Int(
|
|
482
|
-
let cy_fixed = max(0, min(Int(h) - 1, Int(
|
|
499
|
+
let cx = max(0, min(Int(w) - 1, Int(rawX * w)))
|
|
500
|
+
let cy_fixed = max(0, min(Int(h) - 1, Int(rawY * h)))
|
|
483
501
|
|
|
484
502
|
if let measurements = thermalImage.measurements,
|
|
485
503
|
let spot = try? measurements.addSpot(CGPoint(x: cx, y: cy_fixed)) {
|
|
@@ -332,7 +332,8 @@ RCT_EXPORT_METHOD(getTemperatureAt : (nonnull NSNumber *)x y : (
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
RCT_EXPORT_METHOD(getTemperatureAtNormalized : (nonnull NSNumber *)nx y : (
|
|
335
|
-
nonnull NSNumber *)ny
|
|
335
|
+
nonnull NSNumber *)ny rotation : (nonnull NSNumber *)rotation
|
|
336
|
+
resolver : (RCTPromiseResolveBlock)
|
|
336
337
|
resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
337
338
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
338
339
|
id manager = flir_manager_shared();
|
|
@@ -340,11 +341,11 @@ RCT_EXPORT_METHOD(getTemperatureAtNormalized : (nonnull NSNumber *)nx y : (
|
|
|
340
341
|
if (manager &&
|
|
341
342
|
[manager
|
|
342
343
|
respondsToSelector:sel_registerName(
|
|
343
|
-
"getTemperatureAtNormalized:y:")]) {
|
|
344
|
-
temp = ((double (*)(id, SEL, double, double))objc_msgSend)(
|
|
344
|
+
"getTemperatureAtNormalized:y:rotation:")]) {
|
|
345
|
+
temp = ((double (*)(id, SEL, double, double, NSInteger))objc_msgSend)(
|
|
345
346
|
manager,
|
|
346
|
-
sel_registerName("getTemperatureAtNormalized:y:"),
|
|
347
|
-
[nx doubleValue], [ny doubleValue]);
|
|
347
|
+
sel_registerName("getTemperatureAtNormalized:y:rotation:"),
|
|
348
|
+
[nx doubleValue], [ny doubleValue], [rotation integerValue]);
|
|
348
349
|
}
|
|
349
350
|
if (isnan(temp)) {
|
|
350
351
|
if (resolve) resolve([NSNull null]);
|