react-native-rectangle-doc-scanner 7.51.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
|
|
@@ -559,14 +627,7 @@ class CameraController(
|
|
|
559
627
|
val preview = previewSize ?: return
|
|
560
628
|
if (viewWidth == 0f || viewHeight == 0f) return
|
|
561
629
|
|
|
562
|
-
val
|
|
563
|
-
val rotationDegrees = when (rotation) {
|
|
564
|
-
Surface.ROTATION_0 -> 0
|
|
565
|
-
Surface.ROTATION_90 -> 90
|
|
566
|
-
Surface.ROTATION_180 -> 180
|
|
567
|
-
Surface.ROTATION_270 -> 270
|
|
568
|
-
else -> 0
|
|
569
|
-
}
|
|
630
|
+
val rotationDegrees = computeRotationDegrees()
|
|
570
631
|
Log.d(
|
|
571
632
|
TAG,
|
|
572
633
|
"[TRANSFORM] rotation=$rotationDegrees view=${viewWidth}x${viewHeight} preview=${preview.width}x${preview.height}"
|
|
@@ -577,31 +638,30 @@ class CameraController(
|
|
|
577
638
|
val centerX = viewRect.centerX()
|
|
578
639
|
val centerY = viewRect.centerY()
|
|
579
640
|
|
|
580
|
-
val
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
)
|
|
589
|
-
matrix.postScale(scale, scale, centerX, centerY)
|
|
590
|
-
matrix.postRotate(90f * (rotation - 2), centerX, centerY)
|
|
591
|
-
} else {
|
|
592
|
-
val bufferRect = RectF(0f, 0f, preview.width.toFloat(), preview.height.toFloat())
|
|
593
|
-
matrix.setRectToRect(bufferRect, viewRect, Matrix.ScaleToFit.CENTER)
|
|
594
|
-
val scale = max(
|
|
595
|
-
viewWidth / preview.width.toFloat(),
|
|
596
|
-
viewHeight / preview.height.toFloat()
|
|
597
|
-
)
|
|
598
|
-
matrix.postScale(scale, scale, centerX, centerY)
|
|
599
|
-
if (rotation == Surface.ROTATION_180) {
|
|
600
|
-
matrix.postRotate(180f, centerX, centerY)
|
|
601
|
-
}
|
|
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
|
+
|
|
646
|
+
if (rotationDegrees != 0) {
|
|
647
|
+
matrix.postRotate(rotationDegrees.toFloat(), bufferRect.centerX(), bufferRect.centerY())
|
|
648
|
+
matrix.mapRect(rotatedRect, bufferRect)
|
|
602
649
|
}
|
|
603
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
|
+
|
|
604
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
|
+
)
|
|
605
665
|
Log.d(TAG, "[TRANSFORM] Matrix applied successfully")
|
|
606
666
|
}
|
|
607
667
|
|
package/android/src/camera2/kotlin/com/reactnativerectangledocscanner/DocumentScannerView.kt
CHANGED
|
@@ -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
|
-
|
|
213
|
+
cameraController?.mapRectangleToView(rectangle, imageWidth, imageHeight)
|
|
214
|
+
?: DocumentDetector.transformRectangleToViewCoordinates(rectangle, imageWidth, imageHeight, width, height)
|
|
214
215
|
} else {
|
|
215
216
|
null
|
|
216
217
|
}
|