react-native-rectangle-doc-scanner 7.52.0 → 7.53.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.
@@ -67,6 +67,9 @@ class CameraController(
67
67
 
68
68
  private val pendingCapture = AtomicReference<PendingCapture?>()
69
69
  private val analysisInFlight = AtomicBoolean(false)
70
+ private var latestTransform: Matrix? = null
71
+ private var latestBufferWidth = 0
72
+ private var latestBufferHeight = 0
70
73
  private val objectDetector = ObjectDetection.getClient(
71
74
  ObjectDetectorOptions.Builder()
72
75
  .setDetectorMode(ObjectDetectorOptions.STREAM_MODE)
@@ -208,6 +211,71 @@ class CameraController(
208
211
  analysisThread.quitSafely()
209
212
  }
210
213
 
214
+ fun mapRectangleToView(rectangle: Rectangle?, imageWidth: Int, imageHeight: Int): Rectangle? {
215
+ val transform = latestTransform ?: return null
216
+ if (rectangle == null || imageWidth <= 0 || imageHeight <= 0) return null
217
+ if (latestBufferWidth <= 0 || latestBufferHeight <= 0) return null
218
+
219
+ val rotationDegrees = computeRotationDegrees()
220
+ val inverseRotation = (360 - rotationDegrees) % 360
221
+
222
+ fun rotatePoint(point: Point): Point {
223
+ return when (inverseRotation) {
224
+ 90 -> Point(imageHeight - point.y, point.x)
225
+ 180 -> Point(imageWidth - point.x, imageHeight - point.y)
226
+ 270 -> Point(point.y, imageWidth - point.x)
227
+ else -> point
228
+ }
229
+ }
230
+
231
+ val rotated = Rectangle(
232
+ rotatePoint(rectangle.topLeft),
233
+ rotatePoint(rectangle.topRight),
234
+ rotatePoint(rectangle.bottomLeft),
235
+ rotatePoint(rectangle.bottomRight)
236
+ )
237
+
238
+ val bufferWidth = if (inverseRotation == 90 || inverseRotation == 270) {
239
+ imageHeight.toDouble()
240
+ } else {
241
+ imageWidth.toDouble()
242
+ }
243
+ val bufferHeight = if (inverseRotation == 90 || inverseRotation == 270) {
244
+ imageWidth.toDouble()
245
+ } else {
246
+ imageHeight.toDouble()
247
+ }
248
+
249
+ val scaleX = latestBufferWidth.toDouble() / bufferWidth
250
+ val scaleY = latestBufferHeight.toDouble() / bufferHeight
251
+
252
+ fun scalePoint(point: Point): Point {
253
+ return Point(point.x * scaleX, point.y * scaleY)
254
+ }
255
+
256
+ val scaled = Rectangle(
257
+ scalePoint(rotated.topLeft),
258
+ scalePoint(rotated.topRight),
259
+ scalePoint(rotated.bottomLeft),
260
+ scalePoint(rotated.bottomRight)
261
+ )
262
+
263
+ val pts = floatArrayOf(
264
+ scaled.topLeft.x.toFloat(), scaled.topLeft.y.toFloat(),
265
+ scaled.topRight.x.toFloat(), scaled.topRight.y.toFloat(),
266
+ scaled.bottomLeft.x.toFloat(), scaled.bottomLeft.y.toFloat(),
267
+ scaled.bottomRight.x.toFloat(), scaled.bottomRight.y.toFloat()
268
+ )
269
+ transform.mapPoints(pts)
270
+
271
+ return Rectangle(
272
+ Point(pts[0].toDouble(), pts[1].toDouble()),
273
+ Point(pts[2].toDouble(), pts[3].toDouble()),
274
+ Point(pts[4].toDouble(), pts[5].toDouble()),
275
+ Point(pts[6].toDouble(), pts[7].toDouble())
276
+ )
277
+ }
278
+
211
279
  private fun openCamera() {
212
280
  if (cameraDevice != null) {
213
281
  return
@@ -570,22 +638,30 @@ class CameraController(
570
638
  val centerX = viewRect.centerX()
571
639
  val centerY = viewRect.centerY()
572
640
 
573
- val isSwapped = rotationDegrees == 90 || rotationDegrees == 270
574
- val bufferWidth = if (isSwapped) preview.height.toFloat() else preview.width.toFloat()
575
- val bufferHeight = if (isSwapped) preview.width.toFloat() else preview.height.toFloat()
576
- val scale = max(viewWidth / bufferWidth, viewHeight / bufferHeight)
577
- val scaledWidth = bufferWidth * scale
578
- val scaledHeight = bufferHeight * scale
579
- val dx = (viewWidth - scaledWidth) / 2f
580
- val dy = (viewHeight - scaledHeight) / 2f
581
-
582
- matrix.setScale(scale, scale)
583
- matrix.postTranslate(dx, dy)
641
+ val bufferWidth = preview.width.toFloat()
642
+ val bufferHeight = preview.height.toFloat()
643
+ val bufferRect = RectF(0f, 0f, bufferWidth, bufferHeight)
644
+ val rotatedRect = RectF(bufferRect)
645
+
584
646
  if (rotationDegrees != 0) {
585
- matrix.postRotate(rotationDegrees.toFloat(), centerX, centerY)
647
+ matrix.postRotate(rotationDegrees.toFloat(), bufferRect.centerX(), bufferRect.centerY())
648
+ matrix.mapRect(rotatedRect, bufferRect)
586
649
  }
587
650
 
651
+ val scale = max(viewWidth / rotatedRect.width(), viewHeight / rotatedRect.height())
652
+ matrix.postScale(scale, scale, rotatedRect.centerX(), rotatedRect.centerY())
653
+ matrix.postTranslate(centerX - rotatedRect.centerX(), centerY - rotatedRect.centerY())
654
+
588
655
  previewView.setTransform(matrix)
656
+ latestTransform = Matrix(matrix)
657
+ latestBufferWidth = preview.width
658
+ latestBufferHeight = preview.height
659
+ Log.d(
660
+ TAG,
661
+ "[TRANSFORM] viewClass=${previewView.javaClass.name} isTextureView=${previewView is TextureView} " +
662
+ "buffer=${preview.width}x${preview.height} rotated=${rotatedRect.width()}x${rotatedRect.height()} " +
663
+ "scale=$scale center=${centerX}x${centerY} matrix=$matrix"
664
+ )
589
665
  Log.d(TAG, "[TRANSFORM] Matrix applied successfully")
590
666
  }
591
667
 
@@ -210,7 +210,8 @@ class DocumentScannerView(context: ThemedReactContext) : FrameLayout(context), L
210
210
  }
211
211
 
212
212
  val rectangleOnScreen = if (rectangle != null && width > 0 && height > 0) {
213
- DocumentDetector.transformRectangleToViewCoordinates(rectangle, imageWidth, imageHeight, width, height)
213
+ cameraController?.mapRectangleToView(rectangle, imageWidth, imageHeight)
214
+ ?: DocumentDetector.transformRectangleToViewCoordinates(rectangle, imageWidth, imageHeight, width, height)
214
215
  } else {
215
216
  null
216
217
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "7.52.0",
3
+ "version": "7.53.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",