react-native-rectangle-doc-scanner 10.49.0 → 11.0.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.
@@ -545,27 +545,19 @@ class CameraController(
545
545
  val centerX = viewWidth / 2f
546
546
  val centerY = viewHeight / 2f
547
547
 
548
- // For sensor=0 (tablet landscape), we need to manually rotate the buffer
549
- // CameraX only handles rotation automatically for sensor=90 (phone portrait)
550
- // Important: For sensor=0, we need to rotate in the OPPOSITE direction
551
- // When display is 90° (portrait), we need to rotate -90° (270°) to compensate
552
- if (sensorOrientation == 0 && displayRotationDegrees != 0) {
553
- val rotationDegrees = when (displayRotationDegrees) {
554
- 90 -> -90f // Display 90° → Rotate -90° (counter-clockwise)
555
- 180 -> -180f
556
- 270 -> -270f // Or +90f
557
- else -> 0f
558
- }
548
+ val rotationDegrees = ((sensorOrientation + displayRotationDegrees) % 360).toFloat()
549
+
550
+ if (rotationDegrees != 0f) {
551
+ Log.d(TAG, "[TRANSFORM] Applying rotation: ${rotationDegrees}°")
559
552
  matrix.postRotate(rotationDegrees, centerX, centerY)
560
553
  }
561
554
 
562
- // Calculate rotated buffer dimensions
563
- val rotatedBufferWidth = if (sensorOrientation == 0 && (displayRotationDegrees == 90 || displayRotationDegrees == 270)) {
555
+ val rotatedBufferWidth = if (rotationDegrees == 90f || rotationDegrees == 270f) {
564
556
  bufferHeight
565
557
  } else {
566
558
  bufferWidth
567
559
  }
568
- val rotatedBufferHeight = if (sensorOrientation == 0 && (displayRotationDegrees == 90 || displayRotationDegrees == 270)) {
560
+ val rotatedBufferHeight = if (rotationDegrees == 90f || rotationDegrees == 270f) {
569
561
  bufferWidth
570
562
  } else {
571
563
  bufferHeight
@@ -498,36 +498,40 @@ class DocumentDetector {
498
498
  val rectArea = rectWidth * rectHeight
499
499
 
500
500
  // Check if rectangle is too small (less than 15% of view area)
501
+ // or too large (more than 85% - likely detecting screen instead of document)
501
502
  val areaRatio = rectArea / viewArea
502
503
  if (areaRatio < 0.15) {
503
504
  if (BuildConfig.DEBUG) {
504
- Log.d(TAG, "[QUALITY] TOO_FAR: area=${String.format("%.1f", rectArea)}, ratio=${String.format("%.2f", areaRatio)}")
505
+ Log.d(TAG, "[QUALITY] TOO_FAR (small): area=${String.format("%.1f", rectArea)}, ratio=${String.format("%.2f", areaRatio)}")
506
+ }
507
+ return RectangleQuality.TOO_FAR
508
+ }
509
+ if (areaRatio > 0.85) {
510
+ if (BuildConfig.DEBUG) {
511
+ Log.d(TAG, "[QUALITY] TOO_FAR (large): area=${String.format("%.1f", rectArea)}, ratio=${String.format("%.2f", areaRatio)} - likely detecting screen")
505
512
  }
506
513
  return RectangleQuality.TOO_FAR
507
514
  }
508
515
 
509
- // Check angle quality: edges should not be too skewed
510
- // More lenient threshold: 20% of edge length
511
- val topAngleThreshold = max(60.0, topEdgeLength * 0.20)
512
- val bottomAngleThreshold = max(60.0, bottomEdgeLength * 0.20)
513
- val leftAngleThreshold = max(60.0, leftEdgeLength * 0.20)
514
- val rightAngleThreshold = max(60.0, rightEdgeLength * 0.20)
516
+ // Check angle quality using angle ratio instead of absolute difference
517
+ // Edges should be roughly horizontal/vertical (not too skewed)
518
+ val topAngleRatio = if (topEdgeLength > 0) abs(rectangle.topRight.y - rectangle.topLeft.y) / topEdgeLength else 0.0
519
+ val bottomAngleRatio = if (bottomEdgeLength > 0) abs(rectangle.bottomLeft.y - rectangle.bottomRight.y) / bottomEdgeLength else 0.0
520
+ val leftAngleRatio = if (leftEdgeLength > 0) abs(rectangle.topLeft.x - rectangle.bottomLeft.x) / leftEdgeLength else 0.0
521
+ val rightAngleRatio = if (rightEdgeLength > 0) abs(rectangle.topRight.x - rectangle.bottomRight.x) / rightEdgeLength else 0.0
515
522
 
516
- val topYDiff = abs(rectangle.topRight.y - rectangle.topLeft.y)
517
- val bottomYDiff = abs(rectangle.bottomLeft.y - rectangle.bottomRight.y)
518
- val leftXDiff = abs(rectangle.topLeft.x - rectangle.bottomLeft.x)
519
- val rightXDiff = abs(rectangle.topRight.x - rectangle.bottomRight.x)
523
+ // Allow up to 30% skew (sin(~17°) 0.3)
524
+ val maxSkewRatio = 0.3
520
525
 
521
- // Check if edges are too skewed (perspective too extreme)
522
- if (topYDiff > topAngleThreshold ||
523
- bottomYDiff > bottomAngleThreshold ||
524
- leftXDiff > leftAngleThreshold ||
525
- rightXDiff > rightAngleThreshold) {
526
+ if (topAngleRatio > maxSkewRatio ||
527
+ bottomAngleRatio > maxSkewRatio ||
528
+ leftAngleRatio > maxSkewRatio ||
529
+ rightAngleRatio > maxSkewRatio) {
526
530
  if (BuildConfig.DEBUG) {
527
- Log.d(TAG, "[QUALITY] BAD_ANGLE (skew): topY=$topYDiff>${String.format("%.1f", topAngleThreshold)}, " +
528
- "bottomY=$bottomYDiff>${String.format("%.1f", bottomAngleThreshold)}, " +
529
- "leftX=$leftXDiff>${String.format("%.1f", leftAngleThreshold)}, " +
530
- "rightX=$rightXDiff>${String.format("%.1f", rightAngleThreshold)}")
531
+ Log.d(TAG, "[QUALITY] BAD_ANGLE (skew): top=${String.format("%.2f", topAngleRatio)}, " +
532
+ "bottom=${String.format("%.2f", bottomAngleRatio)}, " +
533
+ "left=${String.format("%.2f", leftAngleRatio)}, " +
534
+ "right=${String.format("%.2f", rightAngleRatio)} > $maxSkewRatio")
531
535
  }
532
536
  return RectangleQuality.BAD_ANGLE
533
537
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "10.49.0",
3
+ "version": "11.0.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",