react-native-rectangle-doc-scanner 10.7.0 → 10.8.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.
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
package com.reactnativerectangledocscanner
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.graphics.SurfaceTexture
|
|
4
5
|
import android.util.Log
|
|
6
|
+
import android.util.Size
|
|
7
|
+
import android.view.Surface
|
|
8
|
+
import android.view.TextureView
|
|
5
9
|
import androidx.camera.core.*
|
|
6
10
|
import androidx.camera.lifecycle.ProcessCameraProvider
|
|
7
|
-
import androidx.camera.view.PreviewView
|
|
8
11
|
import androidx.core.content.ContextCompat
|
|
9
12
|
import androidx.lifecycle.LifecycleOwner
|
|
10
13
|
import com.google.mlkit.vision.common.InputImage
|
|
@@ -16,12 +19,12 @@ import java.util.concurrent.Executors
|
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* CameraX-based camera controller for document scanning
|
|
19
|
-
* Handles Preview, ImageAnalysis (ML Kit + OpenCV), and ImageCapture
|
|
22
|
+
* Handles Preview (via TextureView), ImageAnalysis (ML Kit + OpenCV), and ImageCapture
|
|
20
23
|
*/
|
|
21
24
|
class CameraController(
|
|
22
25
|
private val context: Context,
|
|
23
26
|
private val lifecycleOwner: LifecycleOwner,
|
|
24
|
-
private val
|
|
27
|
+
private val textureView: TextureView
|
|
25
28
|
) {
|
|
26
29
|
private var camera: Camera? = null
|
|
27
30
|
private var cameraProvider: ProcessCameraProvider? = null
|
|
@@ -93,19 +96,53 @@ class CameraController(
|
|
|
93
96
|
CameraSelector.DEFAULT_BACK_CAMERA
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
// Preview UseCase
|
|
97
|
-
Log.d(TAG, "[CAMERAX]
|
|
98
|
-
Log.d(TAG, "[CAMERAX]
|
|
99
|
-
Log.d(TAG, "[CAMERAX]
|
|
100
|
-
|
|
99
|
+
// Preview UseCase with TextureView
|
|
100
|
+
Log.d(TAG, "[CAMERAX] TextureView size: ${textureView.width}x${textureView.height}")
|
|
101
|
+
Log.d(TAG, "[CAMERAX] TextureView visibility: ${textureView.visibility}")
|
|
102
|
+
Log.d(TAG, "[CAMERAX] TextureView isAvailable: ${textureView.isAvailable}")
|
|
103
|
+
|
|
101
104
|
preview = Preview.Builder()
|
|
102
105
|
.setTargetResolution(android.util.Size(1920, 1080)) // 16:9 resolution
|
|
103
106
|
.build()
|
|
104
107
|
.also { previewUseCase ->
|
|
105
|
-
Log.d(TAG, "[CAMERAX] Setting SurfaceProvider...")
|
|
106
|
-
|
|
107
|
-
//
|
|
108
|
-
previewUseCase.setSurfaceProvider(ContextCompat.getMainExecutor(context)
|
|
108
|
+
Log.d(TAG, "[CAMERAX] Setting SurfaceProvider for TextureView...")
|
|
109
|
+
|
|
110
|
+
// Set custom SurfaceProvider for TextureView
|
|
111
|
+
previewUseCase.setSurfaceProvider(ContextCompat.getMainExecutor(context)) { request ->
|
|
112
|
+
Log.d(TAG, "[CAMERAX] Surface requested - resolution: ${request.resolution}")
|
|
113
|
+
|
|
114
|
+
val surfaceTexture = textureView.surfaceTexture
|
|
115
|
+
if (surfaceTexture != null) {
|
|
116
|
+
Log.d(TAG, "[CAMERAX] SurfaceTexture available, providing surface")
|
|
117
|
+
surfaceTexture.setDefaultBufferSize(
|
|
118
|
+
request.resolution.width,
|
|
119
|
+
request.resolution.height
|
|
120
|
+
)
|
|
121
|
+
val surface = Surface(surfaceTexture)
|
|
122
|
+
request.provideSurface(surface, ContextCompat.getMainExecutor(context)) { result ->
|
|
123
|
+
Log.d(TAG, "[CAMERAX] Surface provided - result: ${result.resultCode}")
|
|
124
|
+
surface.release()
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
Log.e(TAG, "[CAMERAX] SurfaceTexture is null! Waiting for TextureView to be ready...")
|
|
128
|
+
// Set listener for when SurfaceTexture becomes available
|
|
129
|
+
textureView.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
|
|
130
|
+
override fun onSurfaceTextureAvailable(st: SurfaceTexture, width: Int, height: Int) {
|
|
131
|
+
Log.d(TAG, "[CAMERAX] SurfaceTexture now available ($width x $height)")
|
|
132
|
+
st.setDefaultBufferSize(request.resolution.width, request.resolution.height)
|
|
133
|
+
val surface = Surface(st)
|
|
134
|
+
request.provideSurface(surface, ContextCompat.getMainExecutor(context)) { result ->
|
|
135
|
+
Log.d(TAG, "[CAMERAX] Surface provided (delayed) - result: ${result.resultCode}")
|
|
136
|
+
surface.release()
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {}
|
|
141
|
+
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean = true
|
|
142
|
+
override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
109
146
|
|
|
110
147
|
Log.d(TAG, "[CAMERAX] SurfaceProvider set successfully")
|
|
111
148
|
}
|
|
@@ -147,7 +184,7 @@ class CameraController(
|
|
|
147
184
|
|
|
148
185
|
// Add ImageAnalysis after a short delay to avoid timeout
|
|
149
186
|
if (detectionEnabled) {
|
|
150
|
-
|
|
187
|
+
textureView.post {
|
|
151
188
|
try {
|
|
152
189
|
Log.d(TAG, "[CAMERAX] Adding ImageAnalysis...")
|
|
153
190
|
camera = cameraProvider.bindToLifecycle(
|
|
@@ -166,19 +203,6 @@ class CameraController(
|
|
|
166
203
|
|
|
167
204
|
Log.d(TAG, "[CAMERAX] Camera bound successfully")
|
|
168
205
|
|
|
169
|
-
// Monitor preview stream state
|
|
170
|
-
previewView.previewStreamState.observe(lifecycleOwner) { state ->
|
|
171
|
-
Log.d(TAG, "[CAMERAX] PreviewStreamState changed: $state")
|
|
172
|
-
when (state) {
|
|
173
|
-
androidx.camera.view.PreviewView.StreamState.IDLE ->
|
|
174
|
-
Log.w(TAG, "[CAMERAX] Preview stream is IDLE")
|
|
175
|
-
androidx.camera.view.PreviewView.StreamState.STREAMING ->
|
|
176
|
-
Log.d(TAG, "[CAMERAX] Preview stream is STREAMING ✓")
|
|
177
|
-
else ->
|
|
178
|
-
Log.d(TAG, "[CAMERAX] Preview stream state: $state")
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
206
|
} catch (e: Exception) {
|
|
183
207
|
Log.e(TAG, "[CAMERAX] Use case binding failed", e)
|
|
184
208
|
}
|
|
@@ -353,19 +377,17 @@ class CameraController(
|
|
|
353
377
|
}
|
|
354
378
|
|
|
355
379
|
fun refreshTransform() {
|
|
356
|
-
// CameraX
|
|
357
|
-
|
|
358
|
-
Log.d(TAG, "[CAMERAX] Transform refresh requested - handled automatically by PreviewView")
|
|
380
|
+
// CameraX with TextureView - no manual transform needed
|
|
381
|
+
Log.d(TAG, "[CAMERAX] Transform refresh requested - handled automatically")
|
|
359
382
|
}
|
|
360
383
|
|
|
361
|
-
// Simplified coordinate mapping
|
|
384
|
+
// Simplified coordinate mapping for TextureView
|
|
362
385
|
fun mapRectangleToView(rectangle: Rectangle?, imageWidth: Int, imageHeight: Int): Rectangle? {
|
|
363
386
|
if (rectangle == null || imageWidth <= 0 || imageHeight <= 0) return null
|
|
364
387
|
|
|
365
|
-
//
|
|
366
|
-
|
|
367
|
-
val
|
|
368
|
-
val viewHeight = previewView.height.toFloat()
|
|
388
|
+
// Simple proportional scaling for TextureView
|
|
389
|
+
val viewWidth = textureView.width.toFloat()
|
|
390
|
+
val viewHeight = textureView.height.toFloat()
|
|
369
391
|
|
|
370
392
|
if (viewWidth <= 0 || viewHeight <= 0) return null
|
|
371
393
|
|
|
@@ -389,9 +411,9 @@ class CameraController(
|
|
|
389
411
|
}
|
|
390
412
|
|
|
391
413
|
fun getPreviewViewport(): android.graphics.RectF? {
|
|
392
|
-
// With
|
|
393
|
-
val width =
|
|
394
|
-
val height =
|
|
414
|
+
// With TextureView, the viewport is simply the view bounds
|
|
415
|
+
val width = textureView.width.toFloat()
|
|
416
|
+
val height = textureView.height.toFloat()
|
|
395
417
|
|
|
396
418
|
if (width <= 0 || height <= 0) return null
|
|
397
419
|
|
package/android/src/camera2/kotlin/com/reactnativerectangledocscanner/DocumentScannerView.kt
CHANGED
|
@@ -10,8 +10,8 @@ import android.graphics.PorterDuffXfermode
|
|
|
10
10
|
import org.opencv.core.Point
|
|
11
11
|
import android.util.Log
|
|
12
12
|
import android.view.View
|
|
13
|
+
import android.view.TextureView
|
|
13
14
|
import android.widget.FrameLayout
|
|
14
|
-
import androidx.camera.view.PreviewView
|
|
15
15
|
import androidx.lifecycle.Lifecycle
|
|
16
16
|
import androidx.lifecycle.LifecycleOwner
|
|
17
17
|
import androidx.lifecycle.LifecycleRegistry
|
|
@@ -28,7 +28,7 @@ import kotlin.math.max
|
|
|
28
28
|
|
|
29
29
|
class DocumentScannerView(context: ThemedReactContext) : FrameLayout(context), LifecycleOwner {
|
|
30
30
|
private val themedContext = context
|
|
31
|
-
private val previewView:
|
|
31
|
+
private val previewView: TextureView
|
|
32
32
|
private val overlayView: OverlayView
|
|
33
33
|
private val useNativeOverlay = false
|
|
34
34
|
private var cameraController: CameraController? = null
|
|
@@ -81,21 +81,19 @@ class DocumentScannerView(context: ThemedReactContext) : FrameLayout(context), L
|
|
|
81
81
|
lifecycleRegistry.currentState = Lifecycle.State.INITIALIZED
|
|
82
82
|
Log.d(TAG, "[INIT] Lifecycle state: ${lifecycleRegistry.currentState}")
|
|
83
83
|
|
|
84
|
-
// Create preview
|
|
85
|
-
Log.d(TAG, "[INIT] Creating
|
|
86
|
-
previewView =
|
|
84
|
+
// Create TextureView for camera preview (CameraX compatible)
|
|
85
|
+
Log.d(TAG, "[INIT] Creating TextureView...")
|
|
86
|
+
previewView = TextureView(context).apply {
|
|
87
87
|
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
88
88
|
visibility = View.VISIBLE
|
|
89
89
|
keepScreenOn = true
|
|
90
|
-
implementationMode = PreviewView.ImplementationMode.COMPATIBLE // Use TextureView - more compatible with React Native
|
|
91
|
-
scaleType = PreviewView.ScaleType.FILL_CENTER // Fill and center the preview
|
|
92
90
|
}
|
|
93
|
-
Log.d(TAG, "[INIT]
|
|
94
|
-
Log.d(TAG, "[INIT]
|
|
91
|
+
Log.d(TAG, "[INIT] TextureView created: $previewView")
|
|
92
|
+
Log.d(TAG, "[INIT] TextureView visibility: ${previewView.visibility}")
|
|
95
93
|
|
|
96
|
-
Log.d(TAG, "[INIT] Adding
|
|
94
|
+
Log.d(TAG, "[INIT] Adding TextureView to parent...")
|
|
97
95
|
addView(previewView, 0) // Add at index 0 (back)
|
|
98
|
-
Log.d(TAG, "[INIT]
|
|
96
|
+
Log.d(TAG, "[INIT] TextureView added, childCount: $childCount")
|
|
99
97
|
|
|
100
98
|
// Create overlay view for drawing rectangle
|
|
101
99
|
Log.d(TAG, "[INIT] Creating OverlayView...")
|