react-native-rectangle-doc-scanner 7.6.0 → 7.8.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.
@@ -150,6 +150,10 @@ class CameraController(
150
150
  }
151
151
 
152
152
  try {
153
+ // Use 90 degrees for back camera in portrait mode
154
+ val jpegOrientation = 90
155
+ Log.d(TAG, "[CAPTURE] Setting JPEG_ORIENTATION to $jpegOrientation")
156
+
153
157
  val requestBuilder = device.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE).apply {
154
158
  addTarget(reader.surface)
155
159
  set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE)
@@ -157,7 +161,7 @@ class CameraController(
157
161
  if (torchEnabled) {
158
162
  set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH)
159
163
  }
160
- set(CaptureRequest.JPEG_ORIENTATION, 0)
164
+ set(CaptureRequest.JPEG_ORIENTATION, jpegOrientation)
161
165
  }
162
166
 
163
167
  session.capture(requestBuilder.build(), object : CameraCaptureSession.CaptureCallback() {}, cameraHandler)
@@ -236,8 +240,9 @@ class CameraController(
236
240
  val previewSizes = streamConfigMap.getOutputSizes(SurfaceTexture::class.java)
237
241
  Log.d(TAG, "[CAMERA2] Available preview sizes: ${previewSizes?.take(10)?.joinToString { "${it.width}x${it.height}" }}")
238
242
 
239
- previewSize = chooseBestSize(previewSizes, viewAspect, null, preferClosestAspect = true)
240
- Log.d(TAG, "[CAMERA2] Selected preview size: ${previewSize?.width}x${previewSize?.height}")
243
+ // Use the largest available preview size to fill the screen (like iOS uses full image extent)
244
+ previewSize = previewSizes?.maxByOrNull { it.width * it.height }
245
+ Log.d(TAG, "[CAMERA2] Selected LARGEST preview size: ${previewSize?.width}x${previewSize?.height}")
241
246
 
242
247
  val previewAspect = previewSize?.let { it.width.toDouble() / it.height.toDouble() } ?: viewAspect
243
248
  val analysisSizes = streamConfigMap.getOutputSizes(ImageFormat.YUV_420_888)
@@ -547,28 +552,26 @@ class CameraController(
547
552
  val centerX = viewWidth / 2f
548
553
  val centerY = viewHeight / 2f
549
554
 
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
555
+ // Match iOS behavior: use the full preview extent and scale to fill
554
556
  if (rotation == 270 || rotation == 90) {
555
- // Rotate first
556
- matrix.postRotate(rotation.toFloat(), centerX, centerY)
557
-
558
- // After rotation, the dimensions are swapped
557
+ // After rotation, dimensions are swapped
559
558
  val rotatedWidth = preview.height.toFloat()
560
559
  val rotatedHeight = preview.width.toFloat()
561
560
 
562
561
  Log.d(TAG, "[TRANSFORM] After rotation: ${rotatedWidth}x${rotatedHeight}")
563
562
 
564
- // Calculate scale to fill the view completely (aspect fill/crop mode)
563
+ // Calculate scale to completely fill the view (aspect fill - crop mode like iOS)
564
+ // This will crop the image but fill the entire screen
565
565
  val scaleX = viewWidth / rotatedWidth
566
566
  val scaleY = viewHeight / rotatedHeight
567
567
  val scale = maxOf(scaleX, scaleY)
568
568
 
569
569
  Log.d(TAG, "[TRANSFORM] scaleX=$scaleX scaleY=$scaleY finalScale=$scale")
570
570
 
571
- // Apply scale at center
571
+ // Apply rotation around center first
572
+ matrix.postRotate(rotation.toFloat(), centerX, centerY)
573
+
574
+ // Then scale to fill (will crop excess)
572
575
  matrix.postScale(scale, scale, centerX, centerY)
573
576
  } else {
574
577
  // For 0 or 180 degree rotation
@@ -645,33 +648,18 @@ class CameraController(
645
648
  private fun rotateAndMirror(bitmap: Bitmap, rotationDegrees: Int, mirror: Boolean): Bitmap {
646
649
  Log.d(TAG, "[ROTATE_MIRROR] rotationDegrees=$rotationDegrees mirror=$mirror bitmap=${bitmap.width}x${bitmap.height}")
647
650
 
648
- val matrix = Matrix()
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
658
- }
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")
651
+ // JPEG_ORIENTATION is already set to 90, so the image should already be rotated correctly
652
+ // We only need to apply mirror for front camera
653
+ if (!mirror) {
654
+ // Back camera: no additional processing needed since JPEG_ORIENTATION handles rotation
655
+ Log.d(TAG, "[ROTATE_MIRROR] Back camera: returning bitmap as-is (JPEG_ORIENTATION=90 already applied)")
656
+ return bitmap
666
657
  }
667
658
 
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")
674
- }
659
+ // Front camera: apply horizontal mirror
660
+ val matrix = Matrix()
661
+ matrix.postScale(-1f, 1f, bitmap.width / 2f, bitmap.height / 2f)
662
+ Log.d(TAG, "[ROTATE_MIRROR] Front camera: applied horizontal mirror")
675
663
 
676
664
  return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
677
665
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "7.6.0",
3
+ "version": "7.8.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",