react-native-rectangle-doc-scanner 10.36.0 → 10.38.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,31 +442,17 @@ class CameraController(
442
442
 
443
443
  if (viewWidth <= 0 || viewHeight <= 0) return null
444
444
 
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).
445
+ // Image coordinates are already in display orientation (rotation applied before detection).
446
+ val finalWidth = imageWidth
447
+ val finalHeight = imageHeight
447
448
 
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.
451
- val sensorOrientation = getCameraSensorOrientation()
452
- val displayRotationDegrees = when (textureView.display?.rotation ?: Surface.ROTATION_0) {
453
- Surface.ROTATION_0 -> 0
454
- Surface.ROTATION_90 -> 90
455
- Surface.ROTATION_180 -> 180
456
- Surface.ROTATION_270 -> 270
457
- else -> 0
458
- }
459
-
460
- // Simple fit-center scaling like Camera2 did
461
- // The image analysis coordinates are in the image's coordinate space (imageWidth x imageHeight)
462
- // We just need to scale and center them to the view, matching how Camera2 worked.
463
-
464
- val scaleX = viewWidth / imageWidth.toFloat()
465
- val scaleY = viewHeight / imageHeight.toFloat()
466
- val scale = scaleX.coerceAtMost(scaleY) // Fit (preserve aspect ratio)
449
+ // Apply the same center-crop scaling as the TextureView transform.
450
+ val scaleX = viewWidth / finalWidth.toFloat()
451
+ val scaleY = viewHeight / finalHeight.toFloat()
452
+ val scale = scaleX.coerceAtLeast(scaleY)
467
453
 
468
- val scaledWidth = imageWidth * scale
469
- val scaledHeight = imageHeight * scale
454
+ val scaledWidth = finalWidth * scale
455
+ val scaledHeight = finalHeight * scale
470
456
  val offsetX = (viewWidth - scaledWidth) / 2f
471
457
  val offsetY = (viewHeight - scaledHeight) / 2f
472
458
 
@@ -484,11 +470,10 @@ class CameraController(
484
470
  transformPoint(rectangle.bottomRight)
485
471
  )
486
472
 
487
- Log.d(TAG, "[MAPPING] Simple fit-center: Image ${imageWidth}x${imageHeight}, " +
488
- "View ${viewWidth.toInt()}x${viewHeight.toInt()}, Scale: $scale, " +
489
- "Offset: ($offsetX, $offsetY)")
473
+ Log.d(TAG, "[MAPPING] Image: ${imageWidth}x${imageHeight} → View: ${viewWidth.toInt()}x${viewHeight.toInt()}")
474
+ Log.d(TAG, "[MAPPING] Scale: $scale, Offset: ($offsetX, $offsetY)")
490
475
  Log.d(TAG, "[MAPPING] TL: (${rectangle.topLeft.x}, ${rectangle.topLeft.y}) → " +
491
- "(${result.topLeft.x}, ${result.topLeft.y})")
476
+ "Final: (${result.topLeft.x}, ${result.topLeft.y})")
492
477
 
493
478
  return result
494
479
  }
@@ -553,26 +538,17 @@ class CameraController(
553
538
  bufferHeight
554
539
  }
555
540
 
556
- // Scale to fit within the view while maintaining aspect ratio (no zoom/crop)
541
+ // Scale to fill the view while maintaining aspect ratio (center-crop).
557
542
  val scaleX = viewWidth.toFloat() / rotatedBufferWidth.toFloat()
558
543
  val scaleY = viewHeight.toFloat() / rotatedBufferHeight.toFloat()
559
- val scale = scaleX.coerceAtMost(scaleY) // Use min to fit
544
+ val scale = scaleX.coerceAtLeast(scaleY)
560
545
 
561
546
  Log.d(TAG, "[TRANSFORM] Rotated buffer: ${rotatedBufferWidth}x${rotatedBufferHeight}, ScaleX: $scaleX, ScaleY: $scaleY, Using: $scale")
562
547
 
563
548
  matrix.postScale(scale, scale, centerX, centerY)
564
549
 
565
- // Track the actual preview viewport within the view for clipping overlays.
566
- val scaledWidth = rotatedBufferWidth * scale
567
- val scaledHeight = rotatedBufferHeight * scale
568
- val offsetX = (viewWidth - scaledWidth) / 2f
569
- val offsetY = (viewHeight - scaledHeight) / 2f
570
- previewViewport = android.graphics.RectF(
571
- offsetX,
572
- offsetY,
573
- offsetX + scaledWidth,
574
- offsetY + scaledHeight
575
- )
550
+ // With center-crop, the preview fills the view bounds.
551
+ previewViewport = android.graphics.RectF(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat())
576
552
 
577
553
  textureView.setTransform(matrix)
578
554
  Log.d(TAG, "[TRANSFORM] Transform applied successfully")
@@ -749,7 +749,7 @@ class DocumentScannerView(context: ThemedReactContext) : FrameLayout(context), L
749
749
  if (viewWidth == 0 || viewHeight == 0 || imageWidth == 0 || imageHeight == 0) {
750
750
  return rectangle
751
751
  }
752
- val scale = min(
752
+ val scale = max(
753
753
  viewWidth.toDouble() / imageWidth.toDouble(),
754
754
  viewHeight.toDouble() / imageHeight.toDouble()
755
755
  )
@@ -540,7 +540,7 @@ class DocumentDetector {
540
540
  return rectangle
541
541
  }
542
542
 
543
- val scale = min(
543
+ val scale = max(
544
544
  viewWidth.toDouble() / imageWidth.toDouble(),
545
545
  viewHeight.toDouble() / imageHeight.toDouble()
546
546
  )
@@ -553,10 +553,7 @@ class DocumentDetector {
553
553
  fun mapPoint(point: Point): Point {
554
554
  val x = (point.x * scale) + offsetX
555
555
  val y = (point.y * scale) + offsetY
556
- return Point(
557
- x.coerceIn(0.0, viewWidth.toDouble()),
558
- y.coerceIn(0.0, viewHeight.toDouble())
559
- )
556
+ return Point(x, y)
560
557
  }
561
558
 
562
559
  return Rectangle(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "10.36.0",
3
+ "version": "10.38.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",