react-native-rectangle-doc-scanner 3.206.0 → 3.208.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.
@@ -48,6 +48,7 @@ class CameraController(
48
48
 
49
49
  private var cameraId: String? = null
50
50
  private var sensorOrientation: Int = 0
51
+ private var sensorAspectRatio: Float? = null
51
52
  private var previewSize: Size? = null
52
53
  private var analysisSize: Size? = null
53
54
  private var previewChoices: Array<Size> = emptyArray()
@@ -254,6 +255,10 @@ class CameraController(
254
255
  cameraId = selected
255
256
  val characteristics = cameraManager.getCameraCharacteristics(selected)
256
257
  sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0
258
+ val activeArray = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)
259
+ sensorAspectRatio = activeArray?.let { rect ->
260
+ if (rect.height() != 0) rect.width().toFloat() / rect.height().toFloat() else null
261
+ }
257
262
 
258
263
  val streamConfig = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
259
264
  previewChoices = streamConfig?.getOutputSizes(SurfaceTexture::class.java) ?: emptyArray()
@@ -267,12 +272,16 @@ class CameraController(
267
272
  null
268
273
  }
269
274
 
270
- previewSize = choosePreviewSize(previewChoices, targetRatio)
271
- analysisSize = chooseAnalysisSize(analysisChoices, targetRatio)
275
+ logSizeCandidates("preview", previewChoices, targetRatio, sensorAspectRatio)
276
+ logSizeCandidates("analysis", analysisChoices, targetRatio, sensorAspectRatio)
277
+
278
+ previewSize = choosePreviewSize(previewChoices, targetRatio, sensorAspectRatio)
279
+ analysisSize = chooseAnalysisSize(analysisChoices, targetRatio, sensorAspectRatio)
272
280
  Log.d(
273
281
  TAG,
274
282
  "[CAMERA2] chooseCamera view=${viewWidth}x${viewHeight} ratio=$targetRatio " +
275
- "sensorOrientation=$sensorOrientation preview=$previewSize analysis=$analysisSize"
283
+ "sensorOrientation=$sensorOrientation sensorRatio=$sensorAspectRatio " +
284
+ "preview=$previewSize analysis=$analysisSize"
276
285
  )
277
286
  }
278
287
 
@@ -396,8 +405,8 @@ class CameraController(
396
405
  null
397
406
  }
398
407
 
399
- val newPreview = choosePreviewSize(previewChoices, targetRatio)
400
- val newAnalysis = chooseAnalysisSize(analysisChoices, targetRatio)
408
+ val newPreview = choosePreviewSize(previewChoices, targetRatio, sensorAspectRatio)
409
+ val newAnalysis = chooseAnalysisSize(analysisChoices, targetRatio, sensorAspectRatio)
401
410
 
402
411
  if (newPreview != null && newPreview != previewSize) {
403
412
  previewSize = newPreview
@@ -601,25 +610,23 @@ class CameraController(
601
610
 
602
611
  private fun choosePreviewSize(
603
612
  choices: Array<Size>,
604
- targetRatio: Float?
613
+ targetRatio: Float?,
614
+ sensorRatio: Float?
605
615
  ): Size? {
606
616
  if (choices.isEmpty()) {
607
617
  return null
608
618
  }
609
619
  val candidates = choices.toList()
610
620
 
611
- if (targetRatio == null) {
621
+ val ratioBase = sensorRatio ?: targetRatio
622
+ if (ratioBase == null) {
612
623
  return candidates.maxByOrNull { it.width * it.height }
613
624
  }
614
625
 
615
- val normalizedTarget = targetRatio
626
+ val normalizedTarget = ratioBase
616
627
  val sorted = candidates.sortedWith(
617
628
  compareBy<Size> { size ->
618
- val ratio = if (normalizedTarget < 1f) {
619
- size.height.toFloat() / size.width.toFloat()
620
- } else {
621
- size.width.toFloat() / size.height.toFloat()
622
- }
629
+ val ratio = size.width.toFloat() / size.height.toFloat()
623
630
  kotlin.math.abs(ratio - normalizedTarget)
624
631
  }.thenByDescending { size ->
625
632
  size.width * size.height
@@ -630,7 +637,8 @@ class CameraController(
630
637
 
631
638
  private fun chooseAnalysisSize(
632
639
  choices: Array<Size>,
633
- targetRatio: Float?
640
+ targetRatio: Float?,
641
+ sensorRatio: Float?
634
642
  ): Size? {
635
643
  if (choices.isEmpty()) {
636
644
  return null
@@ -639,18 +647,15 @@ class CameraController(
639
647
  val capped = choices.filter { it.width <= MAX_ANALYSIS_WIDTH && it.height <= MAX_ANALYSIS_HEIGHT }
640
648
  val candidates = if (capped.isNotEmpty()) capped else choices.toList()
641
649
 
642
- if (targetRatio == null) {
650
+ val ratioBase = sensorRatio ?: targetRatio
651
+ if (ratioBase == null) {
643
652
  return candidates.maxByOrNull { it.width * it.height }
644
653
  }
645
654
 
646
- val normalizedTarget = targetRatio
655
+ val normalizedTarget = ratioBase
647
656
  val sorted = candidates.sortedWith(
648
657
  compareBy<Size> { size ->
649
- val ratio = if (normalizedTarget < 1f) {
650
- size.height.toFloat() / size.width.toFloat()
651
- } else {
652
- size.width.toFloat() / size.height.toFloat()
653
- }
658
+ val ratio = size.width.toFloat() / size.height.toFloat()
654
659
  kotlin.math.abs(ratio - normalizedTarget)
655
660
  }.thenByDescending { size ->
656
661
  size.width * size.height
@@ -659,6 +664,46 @@ class CameraController(
659
664
  return sorted.first()
660
665
  }
661
666
 
667
+ private fun logSizeCandidates(
668
+ label: String,
669
+ choices: Array<Size>,
670
+ targetRatio: Float?,
671
+ sensorRatio: Float?
672
+ ) {
673
+ if (choices.isEmpty()) {
674
+ Log.d(TAG, "[CAMERA2] $label sizes: none")
675
+ return
676
+ }
677
+
678
+ val ratioBase = sensorRatio ?: targetRatio
679
+ if (ratioBase == null) {
680
+ Log.d(TAG, "[CAMERA2] $label sizes: ${choices.size}, ratioBase=null")
681
+ return
682
+ }
683
+
684
+ val normalizedTarget = ratioBase
685
+ val sorted = choices.sortedWith(
686
+ compareBy<Size> { size ->
687
+ val ratio = size.width.toFloat() / size.height.toFloat()
688
+ kotlin.math.abs(ratio - normalizedTarget)
689
+ }.thenByDescending { size ->
690
+ size.width * size.height
691
+ }
692
+ )
693
+
694
+ val top = sorted.take(5).joinToString { size ->
695
+ val ratio = size.width.toFloat() / size.height.toFloat()
696
+ val diff = kotlin.math.abs(ratio - normalizedTarget)
697
+ "${size.width}x${size.height}(r=${"%.3f".format(ratio)},d=${"%.3f".format(diff)})"
698
+ }
699
+
700
+ Log.d(
701
+ TAG,
702
+ "[CAMERA2] $label sizes: ${choices.size}, ratioBase=${"%.3f".format(normalizedTarget)} " +
703
+ "sensor=${sensorRatio?.let { "%.3f".format(it) }} target=${targetRatio?.let { "%.3f".format(it) }} top=$top"
704
+ )
705
+ }
706
+
662
707
  private fun startBackgroundThread() {
663
708
  if (backgroundThread != null) {
664
709
  return
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "3.206.0",
3
+ "version": "3.208.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",