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
- previewSize = chooseBestSize(previewSizes, targetPreviewAspect, null, preferClosestAspect = true)
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 rotation = previewView.display?.rotation ?: Surface.ROTATION_0
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 = when (rotation) {
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 (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) bufferHeight else bufferWidth
583
- val rotatedHeight = if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) bufferWidth else bufferHeight
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
- pool.forEach { size ->
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 = pool.minOf { aspectDiff(it) }
631
- val close = pool.filter { aspectDiff(it) <= bestDiff + 0.001 }
632
- val selected = close.maxByOrNull { it.width * it.height } ?: pool.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 = capped.filter { aspectDiff(it) <= ANALYSIS_ASPECT_TOLERANCE }
638
+ val matching = poolForSelection.filter { aspectDiff(it) <= ANALYSIS_ASPECT_TOLERANCE }
638
639
 
639
- return matching.firstOrNull() ?: capped.first()
640
+ return matching.firstOrNull() ?: poolForSelection.first()
640
641
  }
641
642
 
642
643
  private fun rotateAndMirror(bitmap: Bitmap, rotationDegrees: Int, mirror: Boolean): Bitmap {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "7.33.0",
3
+ "version": "7.35.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",