react-native-rectangle-doc-scanner 4.12.0 → 4.14.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.
|
@@ -541,25 +541,25 @@ class CameraController(
|
|
|
541
541
|
val centerX = viewWidth / 2f
|
|
542
542
|
val centerY = viewHeight / 2f
|
|
543
543
|
|
|
544
|
+
// Rotate to match display orientation.
|
|
544
545
|
val matrix = Matrix()
|
|
545
|
-
|
|
546
|
-
// Apply transformations in correct order:
|
|
547
|
-
// 1. Translate to center
|
|
548
|
-
matrix.postTranslate(-centerX, -centerY)
|
|
549
|
-
|
|
550
|
-
// 2. Rotate around origin
|
|
551
546
|
if (rotation != 0) {
|
|
552
|
-
matrix.postRotate(rotation.toFloat())
|
|
547
|
+
matrix.postRotate(rotation.toFloat(), centerX, centerY)
|
|
553
548
|
}
|
|
554
|
-
|
|
555
|
-
// 3. Scale to fill view
|
|
556
|
-
val scale = max(viewWidth / bufferWidth, viewHeight / bufferHeight)
|
|
557
|
-
matrix.postScale(scale, scale)
|
|
558
|
-
|
|
559
|
-
// 4. Translate back to center
|
|
560
|
-
matrix.postTranslate(centerX, centerY)
|
|
561
|
-
|
|
562
549
|
previewView.setTransform(matrix)
|
|
550
|
+
|
|
551
|
+
// Center-crop to fill the view.
|
|
552
|
+
val viewAspect = viewWidth / viewHeight
|
|
553
|
+
val bufferAspect = bufferWidth / bufferHeight
|
|
554
|
+
previewView.pivotX = centerX
|
|
555
|
+
previewView.pivotY = centerY
|
|
556
|
+
if (bufferAspect > viewAspect) {
|
|
557
|
+
previewView.scaleX = bufferAspect / viewAspect
|
|
558
|
+
previewView.scaleY = 1f
|
|
559
|
+
} else {
|
|
560
|
+
previewView.scaleX = 1f
|
|
561
|
+
previewView.scaleY = viewAspect / bufferAspect
|
|
562
|
+
}
|
|
563
563
|
}
|
|
564
564
|
|
|
565
565
|
private fun chooseBestSize(
|
|
@@ -602,11 +602,12 @@ class CameraController(
|
|
|
602
602
|
}
|
|
603
603
|
|
|
604
604
|
val bestDiff = pool.minOf { aspectDiff(it) }
|
|
605
|
-
// Use tight tolerance (0.
|
|
606
|
-
val close = pool.filter { aspectDiff(it) <= bestDiff + 0.
|
|
605
|
+
// Use very tight tolerance (0.001) to get only the best aspect ratio matches
|
|
606
|
+
val close = pool.filter { aspectDiff(it) <= bestDiff + 0.001 }
|
|
607
607
|
|
|
608
|
+
// Among best aspect ratio matches, prefer higher resolution
|
|
608
609
|
val selected = close.maxByOrNull { it.width * it.height } ?: pool.maxByOrNull { it.width * it.height }
|
|
609
|
-
Log.d(TAG, "[SIZE_SELECTION] Best aspect diff: $bestDiff, selected: ${selected?.width}x${selected?.height}")
|
|
610
|
+
Log.d(TAG, "[SIZE_SELECTION] Best aspect diff: $bestDiff, candidates: ${close.size}, selected: ${selected?.width}x${selected?.height}")
|
|
610
611
|
return selected
|
|
611
612
|
}
|
|
612
613
|
|
|
@@ -308,18 +308,14 @@ class DocumentDetector {
|
|
|
308
308
|
* Order points in consistent order: topLeft, topRight, bottomLeft, bottomRight
|
|
309
309
|
*/
|
|
310
310
|
private fun orderPoints(points: Array<Point>): Rectangle {
|
|
311
|
-
//
|
|
312
|
-
val
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
val
|
|
316
|
-
val
|
|
317
|
-
val topRight =
|
|
318
|
-
|
|
319
|
-
// Bottom two points
|
|
320
|
-
val bottomPoints = sorted.takeLast(2).sortedBy { it.x }
|
|
321
|
-
val bottomLeft = bottomPoints[0]
|
|
322
|
-
val bottomRight = bottomPoints[1]
|
|
311
|
+
// Use sum/diff ordering for robustness under rotation.
|
|
312
|
+
val sortedBySum = points.sortedBy { it.x + it.y }
|
|
313
|
+
val sortedByDiff = points.sortedBy { it.x - it.y }
|
|
314
|
+
|
|
315
|
+
val topLeft = sortedBySum.first()
|
|
316
|
+
val bottomRight = sortedBySum.last()
|
|
317
|
+
val topRight = sortedByDiff.first()
|
|
318
|
+
val bottomLeft = sortedByDiff.last()
|
|
323
319
|
|
|
324
320
|
return Rectangle(topLeft, topRight, bottomLeft, bottomRight)
|
|
325
321
|
}
|