react-native-rectangle-doc-scanner 10.6.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,37 +96,51 @@ 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...")
|
|
108
|
+
Log.d(TAG, "[CAMERAX] Setting SurfaceProvider for TextureView...")
|
|
106
109
|
|
|
107
|
-
// Set
|
|
110
|
+
// Set custom SurfaceProvider for TextureView
|
|
108
111
|
previewUseCase.setSurfaceProvider(ContextCompat.getMainExecutor(context)) { request ->
|
|
109
|
-
Log.d(TAG, "[CAMERAX]
|
|
110
|
-
Log.d(TAG, "[CAMERAX] Surface resolution: ${request.resolution}")
|
|
111
|
-
Log.d(TAG, "[CAMERAX] Surface camera: ${request.camera}")
|
|
112
|
+
Log.d(TAG, "[CAMERAX] Surface requested - resolution: ${request.resolution}")
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
val surfaceTexture = (previewView.getChildAt(0) as? android.view.TextureView)?.surfaceTexture
|
|
114
|
+
val surfaceTexture = textureView.surfaceTexture
|
|
115
115
|
if (surfaceTexture != null) {
|
|
116
|
-
Log.d(TAG, "[CAMERAX]
|
|
117
|
-
surfaceTexture.setDefaultBufferSize(
|
|
118
|
-
|
|
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)
|
|
119
122
|
request.provideSurface(surface, ContextCompat.getMainExecutor(context)) { result ->
|
|
120
|
-
Log.d(TAG, "[CAMERAX] Surface result: ${result.resultCode}")
|
|
123
|
+
Log.d(TAG, "[CAMERAX] Surface provided - result: ${result.resultCode}")
|
|
121
124
|
surface.release()
|
|
122
125
|
}
|
|
123
126
|
} else {
|
|
124
|
-
Log.e(TAG, "[CAMERAX]
|
|
125
|
-
//
|
|
126
|
-
|
|
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
|
+
}
|
|
127
144
|
}
|
|
128
145
|
}
|
|
129
146
|
|
|
@@ -167,7 +184,7 @@ class CameraController(
|
|
|
167
184
|
|
|
168
185
|
// Add ImageAnalysis after a short delay to avoid timeout
|
|
169
186
|
if (detectionEnabled) {
|
|
170
|
-
|
|
187
|
+
textureView.post {
|
|
171
188
|
try {
|
|
172
189
|
Log.d(TAG, "[CAMERAX] Adding ImageAnalysis...")
|
|
173
190
|
camera = cameraProvider.bindToLifecycle(
|
|
@@ -186,19 +203,6 @@ class CameraController(
|
|
|
186
203
|
|
|
187
204
|
Log.d(TAG, "[CAMERAX] Camera bound successfully")
|
|
188
205
|
|
|
189
|
-
// Monitor preview stream state
|
|
190
|
-
previewView.previewStreamState.observe(lifecycleOwner) { state ->
|
|
191
|
-
Log.d(TAG, "[CAMERAX] PreviewStreamState changed: $state")
|
|
192
|
-
when (state) {
|
|
193
|
-
androidx.camera.view.PreviewView.StreamState.IDLE ->
|
|
194
|
-
Log.w(TAG, "[CAMERAX] Preview stream is IDLE")
|
|
195
|
-
androidx.camera.view.PreviewView.StreamState.STREAMING ->
|
|
196
|
-
Log.d(TAG, "[CAMERAX] Preview stream is STREAMING ✓")
|
|
197
|
-
else ->
|
|
198
|
-
Log.d(TAG, "[CAMERAX] Preview stream state: $state")
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
206
|
} catch (e: Exception) {
|
|
203
207
|
Log.e(TAG, "[CAMERAX] Use case binding failed", e)
|
|
204
208
|
}
|
|
@@ -373,19 +377,17 @@ class CameraController(
|
|
|
373
377
|
}
|
|
374
378
|
|
|
375
379
|
fun refreshTransform() {
|
|
376
|
-
// CameraX
|
|
377
|
-
|
|
378
|
-
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")
|
|
379
382
|
}
|
|
380
383
|
|
|
381
|
-
// Simplified coordinate mapping
|
|
384
|
+
// Simplified coordinate mapping for TextureView
|
|
382
385
|
fun mapRectangleToView(rectangle: Rectangle?, imageWidth: Int, imageHeight: Int): Rectangle? {
|
|
383
386
|
if (rectangle == null || imageWidth <= 0 || imageHeight <= 0) return null
|
|
384
387
|
|
|
385
|
-
//
|
|
386
|
-
|
|
387
|
-
val
|
|
388
|
-
val viewHeight = previewView.height.toFloat()
|
|
388
|
+
// Simple proportional scaling for TextureView
|
|
389
|
+
val viewWidth = textureView.width.toFloat()
|
|
390
|
+
val viewHeight = textureView.height.toFloat()
|
|
389
391
|
|
|
390
392
|
if (viewWidth <= 0 || viewHeight <= 0) return null
|
|
391
393
|
|
|
@@ -409,9 +411,9 @@ class CameraController(
|
|
|
409
411
|
}
|
|
410
412
|
|
|
411
413
|
fun getPreviewViewport(): android.graphics.RectF? {
|
|
412
|
-
// With
|
|
413
|
-
val width =
|
|
414
|
-
val height =
|
|
414
|
+
// With TextureView, the viewport is simply the view bounds
|
|
415
|
+
val width = textureView.width.toFloat()
|
|
416
|
+
val height = textureView.height.toFloat()
|
|
415
417
|
|
|
416
418
|
if (width <= 0 || height <= 0) return null
|
|
417
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...")
|