react-native-rectangle-doc-scanner 7.4.0 → 7.6.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.
@@ -543,34 +543,48 @@ class CameraController(
543
543
  val rotation = computeRotationDegrees()
544
544
  Log.d(TAG, "[TRANSFORM] rotation=$rotation view=${viewWidth}x${viewHeight} preview=${preview.width}x${preview.height}")
545
545
 
546
- // Calculate buffer dimensions after rotation
547
- val bufferWidth = if (rotation == 90 || rotation == 270) preview.height.toFloat() else preview.width.toFloat()
548
- val bufferHeight = if (rotation == 90 || rotation == 270) preview.width.toFloat() else preview.height.toFloat()
549
-
550
- Log.d(TAG, "[TRANSFORM] buffer after rotation: ${bufferWidth}x${bufferHeight}")
551
-
546
+ val matrix = Matrix()
552
547
  val centerX = viewWidth / 2f
553
548
  val centerY = viewHeight / 2f
554
549
 
555
- val matrix = Matrix()
556
-
557
- // Apply rotation
558
- if (rotation != 0) {
550
+ // For 270 degree rotation (portrait mode with back camera):
551
+ // - The camera sensor output is landscape (1920x1088)
552
+ // - We need to rotate 270 degrees to display it in portrait
553
+ // - Then scale to fill the entire view
554
+ if (rotation == 270 || rotation == 90) {
555
+ // Rotate first
559
556
  matrix.postRotate(rotation.toFloat(), centerX, centerY)
560
- }
561
557
 
562
- // Calculate scale to fill the view (crop mode)
563
- val scaleX = viewWidth / bufferWidth
564
- val scaleY = viewHeight / bufferHeight
565
- val scale = maxOf(scaleX, scaleY)
558
+ // After rotation, the dimensions are swapped
559
+ val rotatedWidth = preview.height.toFloat()
560
+ val rotatedHeight = preview.width.toFloat()
566
561
 
567
- Log.d(TAG, "[TRANSFORM] scaleX=$scaleX scaleY=$scaleY finalScale=$scale")
562
+ Log.d(TAG, "[TRANSFORM] After rotation: ${rotatedWidth}x${rotatedHeight}")
568
563
 
569
- // Apply scale
570
- matrix.postScale(scale, scale, centerX, centerY)
564
+ // Calculate scale to fill the view completely (aspect fill/crop mode)
565
+ val scaleX = viewWidth / rotatedWidth
566
+ val scaleY = viewHeight / rotatedHeight
567
+ val scale = maxOf(scaleX, scaleY)
571
568
 
572
- previewView.setTransform(matrix)
569
+ Log.d(TAG, "[TRANSFORM] scaleX=$scaleX scaleY=$scaleY finalScale=$scale")
570
+
571
+ // Apply scale at center
572
+ matrix.postScale(scale, scale, centerX, centerY)
573
+ } else {
574
+ // For 0 or 180 degree rotation
575
+ val scaleX = viewWidth / preview.width.toFloat()
576
+ val scaleY = viewHeight / preview.height.toFloat()
577
+ val scale = maxOf(scaleX, scaleY)
578
+
579
+ Log.d(TAG, "[TRANSFORM] scaleX=$scaleX scaleY=$scaleY finalScale=$scale")
580
+
581
+ if (rotation != 0) {
582
+ matrix.postRotate(rotation.toFloat(), centerX, centerY)
583
+ }
584
+ matrix.postScale(scale, scale, centerX, centerY)
585
+ }
573
586
 
587
+ previewView.setTransform(matrix)
574
588
  Log.d(TAG, "[TRANSFORM] Matrix applied successfully")
575
589
  }
576
590
 
@@ -629,16 +643,36 @@ class CameraController(
629
643
  }
630
644
 
631
645
  private fun rotateAndMirror(bitmap: Bitmap, rotationDegrees: Int, mirror: Boolean): Bitmap {
632
- if (rotationDegrees == 0 && !mirror) {
633
- return bitmap
634
- }
646
+ Log.d(TAG, "[ROTATE_MIRROR] rotationDegrees=$rotationDegrees mirror=$mirror bitmap=${bitmap.width}x${bitmap.height}")
647
+
635
648
  val matrix = Matrix()
636
- if (mirror) {
637
- matrix.postScale(-1f, 1f, bitmap.width / 2f, bitmap.height / 2f)
649
+
650
+ // For 270 degree rotation (back camera in portrait mode):
651
+ // 1. First rotate 90 degrees (not 270)
652
+ // 2. Then flip horizontally if needed
653
+ // This is because the sensor orientation is 0, but we're holding the phone at 90 degrees
654
+ val actualRotation = when (rotationDegrees) {
655
+ 270 -> 90 // Convert 270 to 90 for correct orientation
656
+ 90 -> 270 // Convert 90 to 270 for front camera
657
+ else -> rotationDegrees
638
658
  }
639
- if (rotationDegrees != 0) {
640
- matrix.postRotate(rotationDegrees.toFloat(), bitmap.width / 2f, bitmap.height / 2f)
659
+
660
+ Log.d(TAG, "[ROTATE_MIRROR] Adjusted rotation: $rotationDegrees -> $actualRotation")
661
+
662
+ // Apply rotation first
663
+ if (actualRotation != 0) {
664
+ matrix.postRotate(actualRotation.toFloat())
665
+ Log.d(TAG, "[ROTATE_MIRROR] Applied rotation: $actualRotation degrees")
666
+ }
667
+
668
+ // Apply mirror for front camera only
669
+ if (mirror) {
670
+ // Front camera needs horizontal flip after rotation
671
+ val rotatedWidth = if (actualRotation == 90 || actualRotation == 270) bitmap.height else bitmap.width
672
+ matrix.postScale(-1f, 1f, rotatedWidth / 2f, 0f)
673
+ Log.d(TAG, "[ROTATE_MIRROR] Applied horizontal flip for front camera")
641
674
  }
675
+
642
676
  return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
643
677
  }
644
678
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "7.4.0",
3
+ "version": "7.6.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",