react-native-rectangle-doc-scanner 7.1.0 → 7.3.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.
@@ -48,10 +48,10 @@ android {
48
48
  main {
49
49
  java.srcDirs += 'src/main/kotlin'
50
50
  java.srcDirs += 'src/common/kotlin'
51
+ // Always include camera2 sources (for fallback when VisionCamera is not used at runtime)
52
+ java.srcDirs += 'src/camera2/kotlin'
51
53
  if (hasVisionCamera) {
52
54
  java.srcDirs += 'src/visioncamera/kotlin'
53
- } else {
54
- java.srcDirs += 'src/camera2/kotlin'
55
55
  }
56
56
  }
57
57
  }
@@ -77,20 +77,18 @@ dependencies {
77
77
  implementation 'androidx.core:core-ktx:1.10.1'
78
78
  implementation 'androidx.appcompat:appcompat:1.6.1'
79
79
 
80
- // CameraX core is needed for ImageProxy in VisionCamera frame processor
80
+ // CameraX dependencies (always included for Camera2 fallback and ImageProxy support)
81
81
  def camerax_version = "1.3.0"
82
82
  implementation "androidx.camera:camera-core:${camerax_version}"
83
+ implementation "androidx.camera:camera-camera2:${camerax_version}"
84
+ implementation "androidx.camera:camera-lifecycle:${camerax_version}"
85
+ implementation "androidx.camera:camera-view:${camerax_version}"
86
+
87
+ // ML Kit object detection for live rectangle hints (Camera2 mode)
88
+ implementation 'com.google.mlkit:object-detection:17.0.1'
83
89
 
84
90
  if (hasVisionCamera) {
85
91
  // VisionCamera mode - include VisionCamera dependency
86
92
  implementation project(':react-native-vision-camera')
87
- } else {
88
- // Camera2 mode - include additional CameraX and ML Kit dependencies
89
- implementation "androidx.camera:camera-camera2:${camerax_version}"
90
- implementation "androidx.camera:camera-lifecycle:${camerax_version}"
91
- implementation "androidx.camera:camera-view:${camerax_version}"
92
-
93
- // ML Kit object detection for live rectangle hints
94
- implementation 'com.google.mlkit:object-detection:17.0.1'
95
93
  }
96
94
  }
@@ -549,25 +549,37 @@ class CameraController(
549
549
  if (viewWidth == 0f || viewHeight == 0f) return
550
550
 
551
551
  val rotation = computeRotationDegrees()
552
+ Log.d(TAG, "[TRANSFORM] rotation=$rotation view=${viewWidth}x${viewHeight} preview=${preview.width}x${preview.height}")
553
+
554
+ // Calculate buffer dimensions after rotation
552
555
  val bufferWidth = if (rotation == 90 || rotation == 270) preview.height.toFloat() else preview.width.toFloat()
553
556
  val bufferHeight = if (rotation == 90 || rotation == 270) preview.width.toFloat() else preview.height.toFloat()
554
557
 
558
+ Log.d(TAG, "[TRANSFORM] buffer after rotation: ${bufferWidth}x${bufferHeight}")
559
+
555
560
  val centerX = viewWidth / 2f
556
561
  val centerY = viewHeight / 2f
557
562
 
558
- // Rotate to match display orientation.
559
563
  val matrix = Matrix()
564
+
565
+ // Apply rotation
560
566
  if (rotation != 0) {
561
567
  matrix.postRotate(rotation.toFloat(), centerX, centerY)
562
568
  }
569
+
570
+ // Calculate scale to fill the view (crop mode)
571
+ val scaleX = viewWidth / bufferWidth
572
+ val scaleY = viewHeight / bufferHeight
573
+ val scale = maxOf(scaleX, scaleY)
574
+
575
+ Log.d(TAG, "[TRANSFORM] scaleX=$scaleX scaleY=$scaleY finalScale=$scale")
576
+
577
+ // Apply scale
578
+ matrix.postScale(scale, scale, centerX, centerY)
579
+
563
580
  previewView.setTransform(matrix)
564
581
 
565
- // Uniform center-crop to fill the view.
566
- val scale = max(viewWidth / bufferWidth, viewHeight / bufferHeight)
567
- previewView.pivotX = centerX
568
- previewView.pivotY = centerY
569
- previewView.scaleX = scale
570
- previewView.scaleY = scale
582
+ Log.d(TAG, "[TRANSFORM] Matrix applied successfully")
571
583
  }
572
584
 
573
585
  private fun chooseBestSize(
@@ -43,22 +43,15 @@ class DocumentScannerModule(reactContext: ReactApplicationContext) :
43
43
  try {
44
44
  val view = uiManager.resolveView(tag)
45
45
 
46
- // Use reflection to avoid compile-time dependency on DocumentScannerView
47
- try {
48
- val docScannerViewClass = Class.forName("com.reactnativerectangledocscanner.DocumentScannerView")
49
- if (docScannerViewClass.isInstance(view)) {
50
- Log.d(TAG, "Found DocumentScannerView, triggering capture with promise")
51
-
52
- // Pass promise to view so it can be resolved when capture completes
53
- val captureMethod = docScannerViewClass.getMethod("captureWithPromise", Promise::class.java)
54
- captureMethod.invoke(view, promise)
55
- } else {
56
- Log.e(TAG, "View with tag $tag is not DocumentScannerView: ${view?.javaClass?.simpleName}")
57
- promise.reject("INVALID_VIEW", "View is not a DocumentScannerView")
58
- }
59
- } catch (e: ClassNotFoundException) {
60
- Log.e(TAG, "DocumentScannerView not available (VisionCamera mode)", e)
61
- promise.reject("VIEW_NOT_AVAILABLE", "Camera2 views not available in VisionCamera mode")
46
+ if (view is DocumentScannerView) {
47
+ Log.d(TAG, "Found DocumentScannerView, triggering capture with promise")
48
+
49
+ // Pass promise to view so it can be resolved when capture completes
50
+ // This matches iOS behavior where promise is resolved with actual image data
51
+ view.captureWithPromise(promise)
52
+ } else {
53
+ Log.e(TAG, "View with tag $tag is not DocumentScannerView: ${view?.javaClass?.simpleName}")
54
+ promise.reject("INVALID_VIEW", "View is not a DocumentScannerView")
62
55
  }
63
56
  } catch (e: Exception) {
64
57
  Log.e(TAG, "Error resolving view", e)
@@ -19,28 +19,11 @@ class DocumentScannerPackage : ReactPackage {
19
19
  }
20
20
 
21
21
  override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
22
- // Only register Camera2-based view managers if VisionCamera is not available
23
- return try {
24
- Class.forName(VISION_CAMERA_REGISTRY)
25
- // VisionCamera is available, no need to register Camera2 view managers
26
- emptyList()
27
- } catch (e: ClassNotFoundException) {
28
- // VisionCamera not available, register Camera2 view managers using reflection
29
- try {
30
- val viewManagers = mutableListOf<ViewManager<*, *>>()
31
-
32
- val docScannerViewManagerClass = Class.forName("com.reactnativerectangledocscanner.DocumentScannerViewManager")
33
- val cameraViewManagerClass = Class.forName("com.reactnativerectangledocscanner.CameraViewManager")
34
-
35
- viewManagers.add(docScannerViewManagerClass.newInstance() as ViewManager<*, *>)
36
- viewManagers.add(cameraViewManagerClass.newInstance() as ViewManager<*, *>)
37
-
38
- viewManagers
39
- } catch (e: Exception) {
40
- Log.e(TAG, "Failed to instantiate Camera2 view managers", e)
41
- emptyList()
42
- }
43
- }
22
+ // Always register Camera2 view managers for fallback support
23
+ return listOf(
24
+ DocumentScannerViewManager(),
25
+ CameraViewManager()
26
+ )
44
27
  }
45
28
 
46
29
  private fun registerVisionCameraPlugin() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "7.1.0",
3
+ "version": "7.3.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",