react-native-rectangle-doc-scanner 7.33.0 → 7.35.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.
|
@@ -249,7 +249,8 @@ class CameraController(
|
|
|
249
249
|
// Prefer 4:3 to match iOS FOV on phones; use view aspect on tablets to reduce crop.
|
|
250
250
|
val isTablet = context.resources.configuration.smallestScreenWidthDp >= 600
|
|
251
251
|
val targetPreviewAspect = if (isTablet) viewAspect else 4.0 / 3.0
|
|
252
|
-
|
|
252
|
+
val minPreviewArea = if (isTablet) 1280 * 720 else 960 * 720
|
|
253
|
+
previewSize = chooseBestSize(previewSizes, targetPreviewAspect, null, minPreviewArea, preferClosestAspect = true)
|
|
253
254
|
?: chooseBestSize(previewSizes, viewAspect, null, preferClosestAspect = true)
|
|
254
255
|
?: previewSizes?.maxByOrNull { it.width * it.height }
|
|
255
256
|
Log.d(TAG, "[CAMERA2] Selected preview size: ${previewSize?.width}x${previewSize?.height}")
|
|
@@ -558,7 +559,7 @@ class CameraController(
|
|
|
558
559
|
val viewHeight = previewView.height.toFloat()
|
|
559
560
|
val preview = previewSize ?: return
|
|
560
561
|
if (viewWidth == 0f || viewHeight == 0f) return
|
|
561
|
-
val
|
|
562
|
+
val rotationDegrees = computeRotationDegrees()
|
|
562
563
|
Log.d(
|
|
563
564
|
TAG,
|
|
564
565
|
"[TRANSFORM] rotation=${displayRotationDegrees()} view=${viewWidth}x${viewHeight} preview=${preview.width}x${preview.height}"
|
|
@@ -567,20 +568,15 @@ class CameraController(
|
|
|
567
568
|
val matrix = Matrix()
|
|
568
569
|
val bufferWidth = preview.width.toFloat()
|
|
569
570
|
val bufferHeight = preview.height.toFloat()
|
|
570
|
-
val rotateDegrees =
|
|
571
|
-
Surface.ROTATION_90 -> -90f
|
|
572
|
-
Surface.ROTATION_180 -> 180f
|
|
573
|
-
Surface.ROTATION_270 -> 90f
|
|
574
|
-
else -> 0f
|
|
575
|
-
}
|
|
571
|
+
val rotateDegrees = -rotationDegrees.toFloat()
|
|
576
572
|
|
|
577
573
|
// Move buffer center to origin, rotate, scale uniformly to fill view, then move to view center.
|
|
578
574
|
matrix.postTranslate(-bufferWidth / 2f, -bufferHeight / 2f)
|
|
579
575
|
if (rotateDegrees != 0f) {
|
|
580
576
|
matrix.postRotate(rotateDegrees)
|
|
581
577
|
}
|
|
582
|
-
val rotatedWidth = if (
|
|
583
|
-
val rotatedHeight = if (
|
|
578
|
+
val rotatedWidth = if (rotationDegrees == 90 || rotationDegrees == 270) bufferHeight else bufferWidth
|
|
579
|
+
val rotatedHeight = if (rotationDegrees == 90 || rotationDegrees == 270) bufferWidth else bufferHeight
|
|
584
580
|
val scale = max(viewWidth / rotatedWidth, viewHeight / rotatedHeight)
|
|
585
581
|
matrix.postScale(scale, scale)
|
|
586
582
|
matrix.postTranslate(viewWidth / 2f, viewHeight / 2f)
|
|
@@ -593,6 +589,7 @@ class CameraController(
|
|
|
593
589
|
sizes: Array<Size>?,
|
|
594
590
|
targetAspect: Double,
|
|
595
591
|
maxArea: Int?,
|
|
592
|
+
minArea: Int? = null,
|
|
596
593
|
preferClosestAspect: Boolean = false
|
|
597
594
|
): Size? {
|
|
598
595
|
if (sizes == null || sizes.isEmpty()) return null
|
|
@@ -608,6 +605,14 @@ class CameraController(
|
|
|
608
605
|
return sorted.first()
|
|
609
606
|
}
|
|
610
607
|
|
|
608
|
+
val minCapped = if (minArea != null) {
|
|
609
|
+
capped.filter { it.width * it.height >= minArea }
|
|
610
|
+
} else {
|
|
611
|
+
capped
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
val poolForSelection = if (minCapped.isNotEmpty()) minCapped else capped
|
|
615
|
+
|
|
611
616
|
fun aspectDiff(size: Size): Double {
|
|
612
617
|
val w = size.width.toDouble()
|
|
613
618
|
val h = size.height.toDouble()
|
|
@@ -617,26 +622,22 @@ class CameraController(
|
|
|
617
622
|
}
|
|
618
623
|
|
|
619
624
|
if (preferClosestAspect) {
|
|
620
|
-
// Avoid tiny preview sizes even if aspect matches; prefer reasonable resolution.
|
|
621
|
-
val minAcceptableArea = 640 * 480
|
|
622
|
-
val pool = capped.filter { it.width * it.height >= minAcceptableArea }.ifEmpty { capped }
|
|
623
|
-
|
|
624
625
|
// Prefer aspect ratio match first, then pick the highest resolution among matches.
|
|
625
|
-
|
|
626
|
+
poolForSelection.forEach { size ->
|
|
626
627
|
val diff = aspectDiff(size)
|
|
627
628
|
Log.d(TAG, "[SIZE_SELECTION] ${size.width}x${size.height} aspect=${size.width.toDouble()/size.height} diff=$diff")
|
|
628
629
|
}
|
|
629
630
|
|
|
630
|
-
val bestDiff =
|
|
631
|
-
val close =
|
|
632
|
-
val selected = close.maxByOrNull { it.width * it.height } ?:
|
|
631
|
+
val bestDiff = poolForSelection.minOf { aspectDiff(it) }
|
|
632
|
+
val close = poolForSelection.filter { aspectDiff(it) <= bestDiff + 0.001 }
|
|
633
|
+
val selected = close.maxByOrNull { it.width * it.height } ?: poolForSelection.maxByOrNull { it.width * it.height }
|
|
633
634
|
Log.d(TAG, "[SIZE_SELECTION] Best aspect diff: $bestDiff, candidates: ${close.size}, selected: ${selected?.width}x${selected?.height}")
|
|
634
635
|
return selected
|
|
635
636
|
}
|
|
636
637
|
|
|
637
|
-
val matching =
|
|
638
|
+
val matching = poolForSelection.filter { aspectDiff(it) <= ANALYSIS_ASPECT_TOLERANCE }
|
|
638
639
|
|
|
639
|
-
return matching.firstOrNull() ?:
|
|
640
|
+
return matching.firstOrNull() ?: poolForSelection.first()
|
|
640
641
|
}
|
|
641
642
|
|
|
642
643
|
private fun rotateAndMirror(bitmap: Bitmap, rotationDegrees: Int, mirror: Boolean): Bitmap {
|