react-native-rectangle-doc-scanner 10.32.0 → 10.33.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.
|
@@ -442,7 +442,12 @@ class CameraController(
|
|
|
442
442
|
|
|
443
443
|
if (viewWidth <= 0 || viewHeight <= 0) return null
|
|
444
444
|
|
|
445
|
-
//
|
|
445
|
+
// The image coordinates are in camera sensor space. We need to transform them
|
|
446
|
+
// to match how the TextureView displays the image (after rotation/scaling).
|
|
447
|
+
|
|
448
|
+
// CameraX provides images in sensor orientation. For a 90° sensor (most phones),
|
|
449
|
+
// the image is rotated 90° relative to natural portrait. We must rotate coordinates
|
|
450
|
+
// to match the final display orientation.
|
|
446
451
|
val sensorOrientation = getCameraSensorOrientation()
|
|
447
452
|
val displayRotationDegrees = when (textureView.display?.rotation ?: Surface.ROTATION_0) {
|
|
448
453
|
Surface.ROTATION_0 -> 0
|
|
@@ -452,10 +457,21 @@ class CameraController(
|
|
|
452
457
|
else -> 0
|
|
453
458
|
}
|
|
454
459
|
|
|
455
|
-
|
|
456
|
-
|
|
460
|
+
// Calculate the rotation needed to display the image correctly in portrait mode.
|
|
461
|
+
// This must match the rotation applied in updateTextureViewTransform.
|
|
462
|
+
val rotationDegrees = when {
|
|
463
|
+
// Tablet with landscape sensor in portrait: add 180° fix for upside-down
|
|
464
|
+
sensorOrientation == 0 && displayRotationDegrees == 90 -> 270f
|
|
465
|
+
// Phone with 90° sensor in portrait: rotate 90° to match
|
|
466
|
+
sensorOrientation == 90 && displayRotationDegrees == 0 -> 90f
|
|
467
|
+
// Default: use display rotation
|
|
468
|
+
else -> displayRotationDegrees.toFloat()
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
Log.d(TAG, "[MAPPING] Image: ${imageWidth}x${imageHeight}, Sensor: ${sensorOrientation}°, " +
|
|
472
|
+
"Display: ${displayRotationDegrees}°, Final rotation: ${rotationDegrees}°")
|
|
457
473
|
|
|
458
|
-
//
|
|
474
|
+
// Apply rotation to coordinates to match display orientation
|
|
459
475
|
fun rotatePoint(point: org.opencv.core.Point): org.opencv.core.Point {
|
|
460
476
|
return when (rotationDegrees.toInt()) {
|
|
461
477
|
90 -> org.opencv.core.Point(
|
|
@@ -474,7 +490,7 @@ class CameraController(
|
|
|
474
490
|
}
|
|
475
491
|
}
|
|
476
492
|
|
|
477
|
-
// Determine
|
|
493
|
+
// Determine dimensions after rotation
|
|
478
494
|
val rotatedImageWidth = if (rotationDegrees == 90f || rotationDegrees == 270f) {
|
|
479
495
|
imageHeight
|
|
480
496
|
} else {
|
|
@@ -486,17 +502,17 @@ class CameraController(
|
|
|
486
502
|
imageHeight
|
|
487
503
|
}
|
|
488
504
|
|
|
489
|
-
//
|
|
505
|
+
// Calculate scaling to fit the rotated image into the view (matching transform)
|
|
490
506
|
val scaleX = viewWidth / rotatedImageWidth.toFloat()
|
|
491
507
|
val scaleY = viewHeight / rotatedImageHeight.toFloat()
|
|
492
|
-
val scale = scaleX.coerceAtMost(scaleY) // Fit (
|
|
508
|
+
val scale = scaleX.coerceAtMost(scaleY) // Fit (preserve aspect ratio)
|
|
493
509
|
|
|
494
510
|
val scaledWidth = rotatedImageWidth * scale
|
|
495
511
|
val scaledHeight = rotatedImageHeight * scale
|
|
496
512
|
val offsetX = (viewWidth - scaledWidth) / 2f
|
|
497
513
|
val offsetY = (viewHeight - scaledHeight) / 2f
|
|
498
514
|
|
|
499
|
-
//
|
|
515
|
+
// Transform coordinates: rotate first, then scale and center
|
|
500
516
|
fun transformPoint(point: org.opencv.core.Point): org.opencv.core.Point {
|
|
501
517
|
val rotated = rotatePoint(point)
|
|
502
518
|
return org.opencv.core.Point(
|
|
@@ -505,12 +521,17 @@ class CameraController(
|
|
|
505
521
|
)
|
|
506
522
|
}
|
|
507
523
|
|
|
508
|
-
|
|
524
|
+
val result = Rectangle(
|
|
509
525
|
transformPoint(rectangle.topLeft),
|
|
510
526
|
transformPoint(rectangle.topRight),
|
|
511
527
|
transformPoint(rectangle.bottomLeft),
|
|
512
528
|
transformPoint(rectangle.bottomRight)
|
|
513
529
|
)
|
|
530
|
+
|
|
531
|
+
Log.d(TAG, "[MAPPING] Original TL: (${rectangle.topLeft.x}, ${rectangle.topLeft.y}) → " +
|
|
532
|
+
"Transformed: (${result.topLeft.x}, ${result.topLeft.y})")
|
|
533
|
+
|
|
534
|
+
return result
|
|
514
535
|
}
|
|
515
536
|
|
|
516
537
|
fun getPreviewViewport(): android.graphics.RectF? {
|
|
@@ -550,10 +571,17 @@ class CameraController(
|
|
|
550
571
|
val centerY = viewHeight / 2f
|
|
551
572
|
|
|
552
573
|
// Calculate rotation from buffer to display coordinates.
|
|
553
|
-
//
|
|
554
|
-
//
|
|
555
|
-
|
|
556
|
-
val rotationDegrees =
|
|
574
|
+
// For portrait apps:
|
|
575
|
+
// - 90° sensor (phones): buffer is landscape → need 90° rotation to portrait
|
|
576
|
+
// - 0° sensor (tablets): buffer is portrait → need displayRotation adjustment
|
|
577
|
+
val rotationDegrees = when {
|
|
578
|
+
// Tablet with landscape sensor in portrait: add 180° fix for upside-down
|
|
579
|
+
sensorOrientation == 0 && displayRotationDegrees == 90 -> 270f
|
|
580
|
+
// Phone with 90° sensor in portrait: rotate 90° to match
|
|
581
|
+
sensorOrientation == 90 && displayRotationDegrees == 0 -> 90f
|
|
582
|
+
// Default: use display rotation
|
|
583
|
+
else -> displayRotationDegrees.toFloat()
|
|
584
|
+
}
|
|
557
585
|
|
|
558
586
|
Log.d(TAG, "[TRANSFORM] Applying rotation: ${rotationDegrees}°")
|
|
559
587
|
|
package/package.json
CHANGED