react-native-rectangle-doc-scanner 3.228.0 → 3.229.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.
@@ -9,6 +9,7 @@ import android.graphics.Matrix
9
9
  import android.graphics.Rect
10
10
  import android.graphics.YuvImage
11
11
  import android.util.Log
12
+ import android.util.Size
12
13
  import android.view.Surface
13
14
  import androidx.camera.core.Camera
14
15
  import androidx.camera.core.CameraSelector
@@ -43,6 +44,9 @@ class CameraController(
43
44
  private val lastFrame = AtomicReference<LastFrame?>()
44
45
  private var analysisBound = false
45
46
  private var pendingBindAttempts = 0
47
+ private var triedLowResFallback = false
48
+ private val streamCheckHandler = android.os.Handler(android.os.Looper.getMainLooper())
49
+ private var streamCheckRunnable: Runnable? = null
46
50
 
47
51
  private var useFrontCamera = false
48
52
  private var detectionEnabled = true
@@ -80,6 +84,7 @@ class CameraController(
80
84
  Log.d(TAG, "[CAMERAX-V6] startCamera called")
81
85
  this.useFrontCamera = useFrontCam
82
86
  this.detectionEnabled = enableDetection
87
+ triedLowResFallback = false
83
88
 
84
89
  if (!hasCameraPermission()) {
85
90
  Log.e(TAG, "[CAMERAX-V6] Camera permission not granted")
@@ -104,6 +109,7 @@ class CameraController(
104
109
  Log.d(TAG, "[CAMERAX-V6] stopCamera called")
105
110
  isAnalysisActive = false
106
111
  analysisHandler.removeCallbacks(analysisRunnable)
112
+ streamCheckRunnable?.let { streamCheckHandler.removeCallbacks(it) }
107
113
  cameraProvider?.unbindAll()
108
114
  analysisBound = false
109
115
  }
@@ -166,7 +172,7 @@ class CameraController(
166
172
  cameraExecutor.shutdown()
167
173
  }
168
174
 
169
- private fun bindCameraUseCases() {
175
+ private fun bindCameraUseCases(useLowRes: Boolean = false) {
170
176
  if (!previewView.isAttachedToWindow || previewView.width == 0 || previewView.height == 0) {
171
177
  if (pendingBindAttempts < 5) {
172
178
  pendingBindAttempts++
@@ -186,14 +192,16 @@ class CameraController(
186
192
 
187
193
  val rotation = previewView.display?.rotation ?: Surface.ROTATION_0
188
194
 
189
- // Build Preview without a fixed size to avoid unsupported stream configs.
190
- preview = Preview.Builder()
195
+ // Build Preview; fall back to a low-res stream if the default config stalls.
196
+ val previewBuilder = Preview.Builder()
191
197
  .setTargetRotation(rotation)
192
- .build()
193
- .also {
194
- // IMPORTANT: Set surface provider BEFORE binding
195
- it.setSurfaceProvider(previewView.surfaceProvider)
196
- }
198
+ if (useLowRes) {
199
+ previewBuilder.setTargetResolution(Size(640, 480))
200
+ }
201
+ preview = previewBuilder.build().also {
202
+ // IMPORTANT: Set surface provider BEFORE binding
203
+ it.setSurfaceProvider(previewView.surfaceProvider)
204
+ }
197
205
 
198
206
  val cameraSelector = if (useFrontCamera) {
199
207
  CameraSelector.DEFAULT_FRONT_CAMERA
@@ -209,18 +217,39 @@ class CameraController(
209
217
  preview
210
218
  )
211
219
 
212
- Log.d(TAG, "[CAMERAX-V9] Preview bound, waiting for capture session to configure...")
220
+ if (useLowRes) {
221
+ Log.d(TAG, "[CAMERAX-V9] Preview bound with low-res fallback (640x480)")
222
+ } else {
223
+ Log.d(TAG, "[CAMERAX-V9] Preview bound, waiting for capture session to configure...")
224
+ }
213
225
 
214
226
  // Log session state after some time
215
227
  android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
216
228
  Log.d(TAG, "[CAMERAX-V9] Camera state check - preview should be working now")
217
229
  }, 6000)
218
230
 
231
+ scheduleStreamCheck(useLowRes)
219
232
  } catch (e: Exception) {
220
233
  Log.e(TAG, "[CAMERAX-V8] Failed to bind preview", e)
221
234
  }
222
235
  }
223
236
 
237
+ private fun scheduleStreamCheck(usingLowRes: Boolean) {
238
+ streamCheckRunnable?.let { streamCheckHandler.removeCallbacks(it) }
239
+ streamCheckRunnable = Runnable {
240
+ val state = previewView.previewStreamState.value
241
+ val streaming = state == PreviewView.StreamState.STREAMING
242
+ if (!streaming && !usingLowRes && !triedLowResFallback) {
243
+ triedLowResFallback = true
244
+ Log.w(TAG, "[CAMERAX-V9] Preview not streaming; retrying with low-res fallback")
245
+ bindCameraUseCases(useLowRes = true)
246
+ } else if (!streaming) {
247
+ Log.w(TAG, "[CAMERAX-V9] Preview still not streaming after fallback")
248
+ }
249
+ }
250
+ streamCheckHandler.postDelayed(streamCheckRunnable!!, 6500)
251
+ }
252
+
224
253
  // Function removed - this device cannot handle ImageCapture + Preview simultaneously
225
254
 
226
255
  private fun captureFrameForAnalysis() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "3.228.0",
3
+ "version": "3.229.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",