react-native-rectangle-doc-scanner 7.15.0 → 7.17.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.
@@ -20,7 +20,6 @@ import android.media.ImageReader
20
20
  import android.os.Handler
21
21
  import android.os.HandlerThread
22
22
  import android.util.Log
23
- import android.util.SparseIntArray
24
23
  import android.util.Size
25
24
  import android.view.Surface
26
25
  import android.view.TextureView
@@ -82,12 +81,6 @@ class CameraController(
82
81
  companion object {
83
82
  private const val TAG = "CameraController"
84
83
  private const val ANALYSIS_ASPECT_TOLERANCE = 0.15
85
- private val ORIENTATIONS = SparseIntArray().apply {
86
- append(Surface.ROTATION_0, 90)
87
- append(Surface.ROTATION_90, 0)
88
- append(Surface.ROTATION_180, 270)
89
- append(Surface.ROTATION_270, 180)
90
- }
91
84
  }
92
85
 
93
86
  private data class PendingCapture(
@@ -492,13 +485,14 @@ class CameraController(
492
485
  val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
493
486
  ?: throw IllegalStateException("Failed to decode JPEG")
494
487
 
495
- val computedRotation = computeRotationDegrees()
496
- val rotation = if (exifRotation == 0 || exifRotation != computedRotation) {
497
- computedRotation
488
+ val rotation = if (exifRotation != 0) exifRotation else computeRotationDegrees()
489
+ val shouldRotate = if (rotation == 90 || rotation == 270) {
490
+ bitmap.width > bitmap.height
498
491
  } else {
499
- exifRotation
492
+ bitmap.height > bitmap.width
500
493
  }
501
- val rotated = rotateAndMirror(bitmap, rotation, useFrontCamera)
494
+ val appliedRotation = if (shouldRotate) rotation else 0
495
+ val rotated = rotateAndMirror(bitmap, appliedRotation, useFrontCamera)
502
496
  val photoFile = File(pending.outputDirectory, "doc_scan_${System.currentTimeMillis()}.jpg")
503
497
  FileOutputStream(photoFile).use { out ->
504
498
  rotated.compress(Bitmap.CompressFormat.JPEG, 95, out)
@@ -535,13 +529,13 @@ class CameraController(
535
529
  }
536
530
 
537
531
  private fun computeRotationDegrees(): Int {
538
- val displayRotation = previewView.display?.rotation ?: Surface.ROTATION_0
539
- val deviceRotation = ORIENTATIONS.get(displayRotation, 0)
540
- var rotation = (sensorOrientation + deviceRotation + 360) % 360
541
- if (useFrontCamera) {
542
- rotation = (360 - rotation) % 360
532
+ val displayRotation = displayRotationDegrees()
533
+ val rotation = if (useFrontCamera) {
534
+ (sensorOrientation + displayRotation) % 360
535
+ } else {
536
+ (sensorOrientation - displayRotation + 360) % 360
543
537
  }
544
- Log.d(TAG, "[ROTATION] sensor=$sensorOrientation display=${displayRotationDegrees()} front=$useFrontCamera -> rotation=$rotation")
538
+ Log.d(TAG, "[ROTATION] sensor=$sensorOrientation display=$displayRotation front=$useFrontCamera -> rotation=$rotation")
545
539
  return rotation
546
540
  }
547
541
 
@@ -566,23 +560,28 @@ class CameraController(
566
560
  Log.d(TAG, "[TRANSFORM] rotation=$rotationDegrees view=${viewWidth}x${viewHeight} preview=${preview.width}x${preview.height}")
567
561
 
568
562
  val matrix = Matrix()
569
- val viewRect = RectF(0f, 0f, viewWidth, viewHeight)
570
- val bufferRect = RectF(0f, 0f, preview.height.toFloat(), preview.width.toFloat())
571
- val centerX = viewRect.centerX()
572
- val centerY = viewRect.centerY()
573
-
574
- if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
575
- bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY())
576
- matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL)
577
- val scale = max(
578
- viewHeight / preview.height.toFloat(),
579
- viewWidth / preview.width.toFloat()
580
- )
581
- matrix.postScale(scale, scale, centerX, centerY)
582
- val rotateDegrees = 90f * (rotation - 2)
563
+ val centerX = viewWidth / 2f
564
+ val centerY = viewHeight / 2f
565
+ val isSwapped = rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270
566
+ val bufferWidth = if (isSwapped) preview.height.toFloat() else preview.width.toFloat()
567
+ val bufferHeight = if (isSwapped) preview.width.toFloat() else preview.height.toFloat()
568
+ val scale = max(viewWidth / bufferWidth, viewHeight / bufferHeight)
569
+ val scaledWidth = bufferWidth * scale
570
+ val scaledHeight = bufferHeight * scale
571
+ val dx = (viewWidth - scaledWidth) / 2f
572
+ val dy = (viewHeight - scaledHeight) / 2f
573
+
574
+ matrix.setScale(scale, scale)
575
+ matrix.postTranslate(dx, dy)
576
+
577
+ if (rotation != Surface.ROTATION_0) {
578
+ val rotateDegrees = when (rotation) {
579
+ Surface.ROTATION_90 -> -90f
580
+ Surface.ROTATION_180 -> 180f
581
+ Surface.ROTATION_270 -> 90f
582
+ else -> 0f
583
+ }
583
584
  matrix.postRotate(rotateDegrees, centerX, centerY)
584
- } else if (rotation == Surface.ROTATION_180) {
585
- matrix.postRotate(180f, centerX, centerY)
586
585
  }
587
586
 
588
587
  previewView.setTransform(matrix)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "7.15.0",
3
+ "version": "7.17.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",