react-native-rectangle-doc-scanner 3.207.0 → 3.209.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,15 +272,16 @@ class CameraController(
|
|
|
267
272
|
null
|
|
268
273
|
}
|
|
269
274
|
|
|
270
|
-
logSizeCandidates("preview", previewChoices, targetRatio)
|
|
271
|
-
logSizeCandidates("analysis", analysisChoices, targetRatio)
|
|
275
|
+
logSizeCandidates("preview", previewChoices, targetRatio, sensorAspectRatio)
|
|
276
|
+
logSizeCandidates("analysis", analysisChoices, targetRatio, sensorAspectRatio)
|
|
272
277
|
|
|
273
|
-
previewSize = choosePreviewSize(previewChoices, targetRatio)
|
|
274
|
-
analysisSize = chooseAnalysisSize(analysisChoices, targetRatio)
|
|
278
|
+
previewSize = choosePreviewSize(previewChoices, targetRatio, sensorAspectRatio)
|
|
279
|
+
analysisSize = chooseAnalysisSize(analysisChoices, targetRatio, sensorAspectRatio)
|
|
275
280
|
Log.d(
|
|
276
281
|
TAG,
|
|
277
282
|
"[CAMERA2] chooseCamera view=${viewWidth}x${viewHeight} ratio=$targetRatio " +
|
|
278
|
-
"sensorOrientation=$sensorOrientation
|
|
283
|
+
"sensorOrientation=$sensorOrientation sensorRatio=$sensorAspectRatio " +
|
|
284
|
+
"preview=$previewSize analysis=$analysisSize"
|
|
279
285
|
)
|
|
280
286
|
}
|
|
281
287
|
|
|
@@ -399,8 +405,8 @@ class CameraController(
|
|
|
399
405
|
null
|
|
400
406
|
}
|
|
401
407
|
|
|
402
|
-
val newPreview = choosePreviewSize(previewChoices, targetRatio)
|
|
403
|
-
val newAnalysis = chooseAnalysisSize(analysisChoices, targetRatio)
|
|
408
|
+
val newPreview = choosePreviewSize(previewChoices, targetRatio, sensorAspectRatio)
|
|
409
|
+
val newAnalysis = chooseAnalysisSize(analysisChoices, targetRatio, sensorAspectRatio)
|
|
404
410
|
|
|
405
411
|
if (newPreview != null && newPreview != previewSize) {
|
|
406
412
|
previewSize = newPreview
|
|
@@ -428,39 +434,29 @@ class CameraController(
|
|
|
428
434
|
}
|
|
429
435
|
|
|
430
436
|
val rotationDegrees = getRotationDegrees()
|
|
431
|
-
val
|
|
432
|
-
|
|
433
|
-
val rotatedBufferWidth = if (rotationDegrees == 90 || rotationDegrees == 270) {
|
|
434
|
-
bufferHeight
|
|
435
|
-
} else {
|
|
436
|
-
bufferWidth
|
|
437
|
-
}
|
|
438
|
-
val rotatedBufferHeight = if (rotationDegrees == 90 || rotationDegrees == 270) {
|
|
439
|
-
bufferWidth
|
|
437
|
+
val bufferRect = if (rotationDegrees == 90 || rotationDegrees == 270) {
|
|
438
|
+
RectF(0f, 0f, previewSize.height.toFloat(), previewSize.width.toFloat())
|
|
440
439
|
} else {
|
|
441
|
-
|
|
440
|
+
RectF(0f, 0f, previewSize.width.toFloat(), previewSize.height.toFloat())
|
|
442
441
|
}
|
|
442
|
+
val viewRect = RectF(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat())
|
|
443
|
+
val centerX = viewRect.centerX()
|
|
444
|
+
val centerY = viewRect.centerY()
|
|
443
445
|
|
|
444
|
-
|
|
445
|
-
val scale = kotlin.math.max(
|
|
446
|
-
viewWidth.toFloat() / rotatedBufferWidth,
|
|
447
|
-
viewHeight.toFloat() / rotatedBufferHeight
|
|
448
|
-
)
|
|
446
|
+
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY())
|
|
449
447
|
|
|
450
448
|
val matrix = Matrix()
|
|
451
|
-
//
|
|
452
|
-
matrix.
|
|
449
|
+
// Scale to fill (center-crop) and then apply rotation around center.
|
|
450
|
+
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL)
|
|
453
451
|
if (rotationDegrees != 0) {
|
|
454
|
-
matrix.postRotate(rotationDegrees.toFloat())
|
|
452
|
+
matrix.postRotate(rotationDegrees.toFloat(), centerX, centerY)
|
|
455
453
|
}
|
|
456
|
-
matrix.postScale(scale, scale)
|
|
457
|
-
matrix.postTranslate(viewWidth / 2f, viewHeight / 2f)
|
|
458
454
|
|
|
459
455
|
previewView.setTransform(matrix)
|
|
460
456
|
Log.d(
|
|
461
457
|
TAG,
|
|
462
|
-
"[CAMERA2] transform view=${viewWidth}x${viewHeight} buffer=${
|
|
463
|
-
"
|
|
458
|
+
"[CAMERA2] transform view=${viewWidth}x${viewHeight} buffer=${previewSize.width}x${previewSize.height} " +
|
|
459
|
+
"rotation=$rotationDegrees"
|
|
464
460
|
)
|
|
465
461
|
}
|
|
466
462
|
|
|
@@ -604,25 +600,23 @@ class CameraController(
|
|
|
604
600
|
|
|
605
601
|
private fun choosePreviewSize(
|
|
606
602
|
choices: Array<Size>,
|
|
607
|
-
targetRatio: Float
|
|
603
|
+
targetRatio: Float?,
|
|
604
|
+
sensorRatio: Float?
|
|
608
605
|
): Size? {
|
|
609
606
|
if (choices.isEmpty()) {
|
|
610
607
|
return null
|
|
611
608
|
}
|
|
612
609
|
val candidates = choices.toList()
|
|
613
610
|
|
|
614
|
-
|
|
611
|
+
val ratioBase = sensorRatio ?: targetRatio
|
|
612
|
+
if (ratioBase == null) {
|
|
615
613
|
return candidates.maxByOrNull { it.width * it.height }
|
|
616
614
|
}
|
|
617
615
|
|
|
618
|
-
val normalizedTarget =
|
|
616
|
+
val normalizedTarget = ratioBase
|
|
619
617
|
val sorted = candidates.sortedWith(
|
|
620
618
|
compareBy<Size> { size ->
|
|
621
|
-
val ratio =
|
|
622
|
-
size.height.toFloat() / size.width.toFloat()
|
|
623
|
-
} else {
|
|
624
|
-
size.width.toFloat() / size.height.toFloat()
|
|
625
|
-
}
|
|
619
|
+
val ratio = size.width.toFloat() / size.height.toFloat()
|
|
626
620
|
kotlin.math.abs(ratio - normalizedTarget)
|
|
627
621
|
}.thenByDescending { size ->
|
|
628
622
|
size.width * size.height
|
|
@@ -633,7 +627,8 @@ class CameraController(
|
|
|
633
627
|
|
|
634
628
|
private fun chooseAnalysisSize(
|
|
635
629
|
choices: Array<Size>,
|
|
636
|
-
targetRatio: Float
|
|
630
|
+
targetRatio: Float?,
|
|
631
|
+
sensorRatio: Float?
|
|
637
632
|
): Size? {
|
|
638
633
|
if (choices.isEmpty()) {
|
|
639
634
|
return null
|
|
@@ -642,18 +637,15 @@ class CameraController(
|
|
|
642
637
|
val capped = choices.filter { it.width <= MAX_ANALYSIS_WIDTH && it.height <= MAX_ANALYSIS_HEIGHT }
|
|
643
638
|
val candidates = if (capped.isNotEmpty()) capped else choices.toList()
|
|
644
639
|
|
|
645
|
-
|
|
640
|
+
val ratioBase = sensorRatio ?: targetRatio
|
|
641
|
+
if (ratioBase == null) {
|
|
646
642
|
return candidates.maxByOrNull { it.width * it.height }
|
|
647
643
|
}
|
|
648
644
|
|
|
649
|
-
val normalizedTarget =
|
|
645
|
+
val normalizedTarget = ratioBase
|
|
650
646
|
val sorted = candidates.sortedWith(
|
|
651
647
|
compareBy<Size> { size ->
|
|
652
|
-
val ratio =
|
|
653
|
-
size.height.toFloat() / size.width.toFloat()
|
|
654
|
-
} else {
|
|
655
|
-
size.width.toFloat() / size.height.toFloat()
|
|
656
|
-
}
|
|
648
|
+
val ratio = size.width.toFloat() / size.height.toFloat()
|
|
657
649
|
kotlin.math.abs(ratio - normalizedTarget)
|
|
658
650
|
}.thenByDescending { size ->
|
|
659
651
|
size.width * size.height
|
|
@@ -665,26 +657,24 @@ class CameraController(
|
|
|
665
657
|
private fun logSizeCandidates(
|
|
666
658
|
label: String,
|
|
667
659
|
choices: Array<Size>,
|
|
668
|
-
targetRatio: Float
|
|
660
|
+
targetRatio: Float?,
|
|
661
|
+
sensorRatio: Float?
|
|
669
662
|
) {
|
|
670
663
|
if (choices.isEmpty()) {
|
|
671
664
|
Log.d(TAG, "[CAMERA2] $label sizes: none")
|
|
672
665
|
return
|
|
673
666
|
}
|
|
674
667
|
|
|
675
|
-
|
|
676
|
-
|
|
668
|
+
val ratioBase = sensorRatio ?: targetRatio
|
|
669
|
+
if (ratioBase == null) {
|
|
670
|
+
Log.d(TAG, "[CAMERA2] $label sizes: ${choices.size}, ratioBase=null")
|
|
677
671
|
return
|
|
678
672
|
}
|
|
679
673
|
|
|
680
|
-
val normalizedTarget =
|
|
674
|
+
val normalizedTarget = ratioBase
|
|
681
675
|
val sorted = choices.sortedWith(
|
|
682
676
|
compareBy<Size> { size ->
|
|
683
|
-
val ratio =
|
|
684
|
-
size.height.toFloat() / size.width.toFloat()
|
|
685
|
-
} else {
|
|
686
|
-
size.width.toFloat() / size.height.toFloat()
|
|
687
|
-
}
|
|
677
|
+
val ratio = size.width.toFloat() / size.height.toFloat()
|
|
688
678
|
kotlin.math.abs(ratio - normalizedTarget)
|
|
689
679
|
}.thenByDescending { size ->
|
|
690
680
|
size.width * size.height
|
|
@@ -692,16 +682,16 @@ class CameraController(
|
|
|
692
682
|
)
|
|
693
683
|
|
|
694
684
|
val top = sorted.take(5).joinToString { size ->
|
|
695
|
-
val ratio =
|
|
696
|
-
size.height.toFloat() / size.width.toFloat()
|
|
697
|
-
} else {
|
|
698
|
-
size.width.toFloat() / size.height.toFloat()
|
|
699
|
-
}
|
|
685
|
+
val ratio = size.width.toFloat() / size.height.toFloat()
|
|
700
686
|
val diff = kotlin.math.abs(ratio - normalizedTarget)
|
|
701
687
|
"${size.width}x${size.height}(r=${"%.3f".format(ratio)},d=${"%.3f".format(diff)})"
|
|
702
688
|
}
|
|
703
689
|
|
|
704
|
-
Log.d(
|
|
690
|
+
Log.d(
|
|
691
|
+
TAG,
|
|
692
|
+
"[CAMERA2] $label sizes: ${choices.size}, ratioBase=${"%.3f".format(normalizedTarget)} " +
|
|
693
|
+
"sensor=${sensorRatio?.let { "%.3f".format(it) }} target=${targetRatio?.let { "%.3f".format(it) }} top=$top"
|
|
694
|
+
)
|
|
705
695
|
}
|
|
706
696
|
|
|
707
697
|
private fun startBackgroundThread() {
|
package/package.json
CHANGED