react-native-rectangle-doc-scanner 10.48.0 → 10.50.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.
@@ -471,8 +471,8 @@ class DocumentDetector {
471
471
  }
472
472
 
473
473
  /**
474
- * Evaluate rectangle quality in view coordinates (closer to iOS behavior).
475
- * Improved thresholds for better detection accuracy.
474
+ * Evaluate rectangle quality in view coordinates (iOS-like behavior).
475
+ * Focuses on rectangle size and angle quality.
476
476
  */
477
477
  fun evaluateRectangleQualityInView(
478
478
  rectangle: Rectangle,
@@ -484,6 +484,7 @@ class DocumentDetector {
484
484
  }
485
485
 
486
486
  val minDim = kotlin.math.min(viewWidth.toDouble(), viewHeight.toDouble())
487
+ val viewArea = viewWidth.toDouble() * viewHeight.toDouble()
487
488
 
488
489
  // Calculate actual edge lengths for better angle evaluation
489
490
  val topEdgeLength = distance(rectangle.topLeft, rectangle.topRight)
@@ -491,40 +492,59 @@ class DocumentDetector {
491
492
  val leftEdgeLength = distance(rectangle.topLeft, rectangle.bottomLeft)
492
493
  val rightEdgeLength = distance(rectangle.topRight, rectangle.bottomRight)
493
494
 
494
- // Use more lenient threshold: 12% of minimum dimension (reduced from 18%)
495
- // This allows for more realistic perspective angles
496
- val angleThreshold = max(80.0, minDim * 0.12)
495
+ // Calculate rectangle area (approximate using bounding box)
496
+ val rectWidth = max(topEdgeLength, bottomEdgeLength)
497
+ val rectHeight = max(leftEdgeLength, rightEdgeLength)
498
+ val rectArea = rectWidth * rectHeight
497
499
 
498
- val topYDiff = abs(rectangle.topRight.y - rectangle.topLeft.y)
499
- val bottomYDiff = abs(rectangle.bottomLeft.y - rectangle.bottomRight.y)
500
- val leftXDiff = abs(rectangle.topLeft.x - rectangle.bottomLeft.x)
501
- val rightXDiff = abs(rectangle.topRight.x - rectangle.bottomRight.x)
500
+ // Check if rectangle is too small (less than 15% of view area)
501
+ val areaRatio = rectArea / viewArea
502
+ if (areaRatio < 0.15) {
503
+ if (BuildConfig.DEBUG) {
504
+ Log.d(TAG, "[QUALITY] TOO_FAR: area=${String.format("%.1f", rectArea)}, ratio=${String.format("%.2f", areaRatio)}")
505
+ }
506
+ return RectangleQuality.TOO_FAR
507
+ }
508
+
509
+ // Check angle quality using angle ratio instead of absolute difference
510
+ // Edges should be roughly horizontal/vertical (not too skewed)
511
+ val topAngleRatio = if (topEdgeLength > 0) abs(rectangle.topRight.y - rectangle.topLeft.y) / topEdgeLength else 0.0
512
+ val bottomAngleRatio = if (bottomEdgeLength > 0) abs(rectangle.bottomLeft.y - rectangle.bottomRight.y) / bottomEdgeLength else 0.0
513
+ val leftAngleRatio = if (leftEdgeLength > 0) abs(rectangle.topLeft.x - rectangle.bottomLeft.x) / leftEdgeLength else 0.0
514
+ val rightAngleRatio = if (rightEdgeLength > 0) abs(rectangle.topRight.x - rectangle.bottomRight.x) / rightEdgeLength else 0.0
515
+
516
+ // Allow up to 30% skew (sin(~17°) ≈ 0.3)
517
+ val maxSkewRatio = 0.3
502
518
 
503
- // Check if edges are too skewed (perspective too extreme)
504
- if (topYDiff > angleThreshold || bottomYDiff > angleThreshold ||
505
- leftXDiff > angleThreshold || rightXDiff > angleThreshold) {
519
+ if (topAngleRatio > maxSkewRatio ||
520
+ bottomAngleRatio > maxSkewRatio ||
521
+ leftAngleRatio > maxSkewRatio ||
522
+ rightAngleRatio > maxSkewRatio) {
523
+ if (BuildConfig.DEBUG) {
524
+ Log.d(TAG, "[QUALITY] BAD_ANGLE (skew): top=${String.format("%.2f", topAngleRatio)}, " +
525
+ "bottom=${String.format("%.2f", bottomAngleRatio)}, " +
526
+ "left=${String.format("%.2f", leftAngleRatio)}, " +
527
+ "right=${String.format("%.2f", rightAngleRatio)} > $maxSkewRatio")
528
+ }
506
529
  return RectangleQuality.BAD_ANGLE
507
530
  }
508
531
 
509
- // Additional check: opposite edges should be somewhat similar in length
510
- // Allow up to 60% difference (more lenient for perspective)
532
+ // Check opposite edge ratio (perspective check)
533
+ // More lenient: allow 3x difference
511
534
  val topBottomRatio = if (bottomEdgeLength > 0) topEdgeLength / bottomEdgeLength else 0.0
512
535
  val leftRightRatio = if (rightEdgeLength > 0) leftEdgeLength / rightEdgeLength else 0.0
513
- if (topBottomRatio < 0.4 || topBottomRatio > 2.5 ||
514
- leftRightRatio < 0.4 || leftRightRatio > 2.5) {
536
+ if (topBottomRatio < 0.33 || topBottomRatio > 3.0 ||
537
+ leftRightRatio < 0.33 || leftRightRatio > 3.0) {
538
+ if (BuildConfig.DEBUG) {
539
+ Log.d(TAG, "[QUALITY] BAD_ANGLE (ratio): topBottom=${String.format("%.2f", topBottomRatio)}, " +
540
+ "leftRight=${String.format("%.2f", leftRightRatio)}")
541
+ }
515
542
  return RectangleQuality.BAD_ANGLE
516
543
  }
517
544
 
518
- // More lenient margin check: 8% of minimum dimension (increased from 5%)
519
- val margin = max(80.0, minDim * 0.08)
520
- if (rectangle.topLeft.y > margin ||
521
- rectangle.topRight.y > margin ||
522
- rectangle.bottomLeft.y < (viewHeight - margin) ||
523
- rectangle.bottomRight.y < (viewHeight - margin)
524
- ) {
525
- return RectangleQuality.TOO_FAR
545
+ if (BuildConfig.DEBUG) {
546
+ Log.d(TAG, "[QUALITY] GOOD: area=${String.format("%.1f", rectArea)}, ratio=${String.format("%.2f", areaRatio)}")
526
547
  }
527
-
528
548
  return RectangleQuality.GOOD
529
549
  }
530
550
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "10.48.0",
3
+ "version": "10.50.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",