react-native-rectangle-doc-scanner 7.10.0 → 7.12.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.
@@ -35,7 +35,6 @@ import java.io.ByteArrayInputStream
35
35
  import java.util.concurrent.atomic.AtomicReference
36
36
  import java.util.concurrent.atomic.AtomicBoolean
37
37
  import kotlin.math.abs
38
- import kotlin.math.max
39
38
  import kotlin.math.min
40
39
 
41
40
  class CameraController(
@@ -485,7 +484,8 @@ class CameraController(
485
484
  val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
486
485
  ?: throw IllegalStateException("Failed to decode JPEG")
487
486
 
488
- val rotated = rotateAndMirror(bitmap, exifRotation, useFrontCamera)
487
+ val rotation = if (exifRotation != 0) exifRotation else computeRotationDegrees()
488
+ val rotated = rotateAndMirror(bitmap, rotation, useFrontCamera)
489
489
  val photoFile = File(pending.outputDirectory, "doc_scan_${System.currentTimeMillis()}.jpg")
490
490
  FileOutputStream(photoFile).use { out ->
491
491
  rotated.compress(Bitmap.CompressFormat.JPEG, 95, out)
@@ -523,15 +523,11 @@ class CameraController(
523
523
 
524
524
  private fun computeRotationDegrees(): Int {
525
525
  val displayRotation = displayRotationDegrees()
526
-
527
- // For back camera with sensor orientation 0 and display rotation 90 (portrait),
528
- // we need 270 degree rotation to display correctly
529
526
  val rotation = if (useFrontCamera) {
530
527
  (sensorOrientation + displayRotation) % 360
531
528
  } else {
532
529
  (sensorOrientation - displayRotation + 360) % 360
533
530
  }
534
-
535
531
  Log.d(TAG, "[ROTATION] sensor=$sensorOrientation display=$displayRotation front=$useFrontCamera -> rotation=$rotation")
536
532
  return rotation
537
533
  }
@@ -552,47 +548,26 @@ class CameraController(
552
548
  val viewHeight = previewView.height.toFloat()
553
549
  val preview = previewSize ?: return
554
550
  if (viewWidth == 0f || viewHeight == 0f) return
555
-
556
- val rotation = computeRotationDegrees()
557
- Log.d(TAG, "[TRANSFORM] rotation=$rotation view=${viewWidth}x${viewHeight} preview=${preview.width}x${preview.height}")
551
+ val rotation = previewView.display?.rotation ?: Surface.ROTATION_0
552
+ val rotationDegrees = displayRotationDegrees()
553
+ Log.d(TAG, "[TRANSFORM] rotation=$rotationDegrees view=${viewWidth}x${viewHeight} preview=${preview.width}x${preview.height}")
558
554
 
559
555
  val matrix = Matrix()
560
- val centerX = viewWidth / 2f
561
- val centerY = viewHeight / 2f
562
-
563
- // Match iOS behavior: use the full preview extent and scale to fill
564
- if (rotation == 270 || rotation == 90) {
565
- // After rotation, dimensions are swapped
566
- val rotatedWidth = preview.height.toFloat()
567
- val rotatedHeight = preview.width.toFloat()
568
-
569
- Log.d(TAG, "[TRANSFORM] After rotation: ${rotatedWidth}x${rotatedHeight}")
570
-
571
- // Calculate scale to completely fill the view (aspect fill - crop mode like iOS)
572
- // This will crop the image but fill the entire screen
573
- val scaleX = viewWidth / rotatedWidth
574
- val scaleY = viewHeight / rotatedHeight
575
- val scale = maxOf(scaleX, scaleY)
576
-
577
- Log.d(TAG, "[TRANSFORM] scaleX=$scaleX scaleY=$scaleY finalScale=$scale")
578
-
579
- // Apply rotation around center first
580
- matrix.postRotate(rotation.toFloat(), centerX, centerY)
581
-
582
- // Then scale to fill (will crop excess)
583
- matrix.postScale(scale, scale, centerX, centerY)
556
+ val viewRect = RectF(0f, 0f, viewWidth, viewHeight)
557
+ val bufferRect = RectF(0f, 0f, preview.height.toFloat(), preview.width.toFloat())
558
+ val centerX = viewRect.centerX()
559
+ val centerY = viewRect.centerY()
560
+
561
+ if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
562
+ bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY())
563
+ matrix.setRectToRect(bufferRect, viewRect, Matrix.ScaleToFit.CENTER)
564
+ val rotateDegrees = if (rotation == Surface.ROTATION_90) -90f else 90f
565
+ matrix.postRotate(rotateDegrees, centerX, centerY)
584
566
  } else {
585
- // For 0 or 180 degree rotation
586
- val scaleX = viewWidth / preview.width.toFloat()
587
- val scaleY = viewHeight / preview.height.toFloat()
588
- val scale = maxOf(scaleX, scaleY)
589
-
590
- Log.d(TAG, "[TRANSFORM] scaleX=$scaleX scaleY=$scaleY finalScale=$scale")
591
-
592
- if (rotation != 0) {
593
- matrix.postRotate(rotation.toFloat(), centerX, centerY)
567
+ matrix.setRectToRect(bufferRect, viewRect, Matrix.ScaleToFit.CENTER)
568
+ if (rotation == Surface.ROTATION_180) {
569
+ matrix.postRotate(180f, centerX, centerY)
594
570
  }
595
- matrix.postScale(scale, scale, centerX, centerY)
596
571
  }
597
572
 
598
573
  previewView.setTransform(matrix)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "7.10.0",
3
+ "version": "7.12.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",