react-native-rectangle-doc-scanner 3.198.0 → 3.200.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.
@@ -244,8 +244,16 @@ class CameraController(
244
244
  val previewChoices = streamConfig?.getOutputSizes(SurfaceTexture::class.java) ?: emptyArray()
245
245
  val analysisChoices = streamConfig?.getOutputSizes(ImageFormat.YUV_420_888) ?: emptyArray()
246
246
 
247
- previewSize = chooseSize(previewChoices, MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT)
248
- analysisSize = chooseSize(analysisChoices, MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT)
247
+ val viewWidth = if (previewView.width > 0) previewView.width else context.resources.displayMetrics.widthPixels
248
+ val viewHeight = if (previewView.height > 0) previewView.height else context.resources.displayMetrics.heightPixels
249
+ val targetRatio = if (viewWidth > 0 && viewHeight > 0) {
250
+ viewWidth.toFloat() / viewHeight.toFloat()
251
+ } else {
252
+ null
253
+ }
254
+
255
+ previewSize = chooseSize(previewChoices, MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT, targetRatio)
256
+ analysisSize = chooseSize(analysisChoices, MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT, targetRatio)
249
257
  Log.d(TAG, "[CAMERA2] Selected sizes - preview: $previewSize, analysis: $analysisSize")
250
258
  }
251
259
 
@@ -358,25 +366,32 @@ class CameraController(
358
366
  }
359
367
 
360
368
  val rotationDegrees = getRotationDegrees()
361
- val matrix = Matrix()
362
- val viewRect = RectF(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat())
363
- val bufferRect = if (rotationDegrees == 90 || rotationDegrees == 270) {
364
- RectF(0f, 0f, previewSize.height.toFloat(), previewSize.width.toFloat())
369
+ val bufferWidth = previewSize.width.toFloat()
370
+ val bufferHeight = previewSize.height.toFloat()
371
+ val rotatedBufferWidth = if (rotationDegrees == 90 || rotationDegrees == 270) {
372
+ bufferHeight
365
373
  } else {
366
- RectF(0f, 0f, previewSize.width.toFloat(), previewSize.height.toFloat())
374
+ bufferWidth
375
+ }
376
+ val rotatedBufferHeight = if (rotationDegrees == 90 || rotationDegrees == 270) {
377
+ bufferWidth
378
+ } else {
379
+ bufferHeight
367
380
  }
368
- val centerX = viewRect.centerX()
369
- val centerY = viewRect.centerY()
370
381
 
371
- bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY())
372
- // Fill the view while preserving aspect ratio (center-crop).
373
- matrix.setRectToRect(bufferRect, viewRect, Matrix.ScaleToFit.FILL)
382
+ val scale = kotlin.math.min(
383
+ viewWidth.toFloat() / rotatedBufferWidth,
384
+ viewHeight.toFloat() / rotatedBufferHeight
385
+ )
374
386
 
375
- when (rotationDegrees) {
376
- 90 -> matrix.postRotate(90f, centerX, centerY)
377
- 180 -> matrix.postRotate(180f, centerX, centerY)
378
- 270 -> matrix.postRotate(270f, centerX, centerY)
387
+ val matrix = Matrix()
388
+ // Center buffer at origin, rotate, scale to fit, then move to view center.
389
+ matrix.postTranslate(-bufferWidth / 2f, -bufferHeight / 2f)
390
+ if (rotationDegrees != 0) {
391
+ matrix.postRotate(rotationDegrees.toFloat())
379
392
  }
393
+ matrix.postScale(scale, scale)
394
+ matrix.postTranslate(viewWidth / 2f, viewHeight / 2f)
380
395
 
381
396
  previewView.setTransform(matrix)
382
397
  }
@@ -495,13 +510,33 @@ class CameraController(
495
510
  }
496
511
  }
497
512
 
498
- private fun chooseSize(choices: Array<Size>, maxWidth: Int, maxHeight: Int): Size? {
513
+ private fun chooseSize(
514
+ choices: Array<Size>,
515
+ maxWidth: Int,
516
+ maxHeight: Int,
517
+ targetRatio: Float?
518
+ ): Size? {
499
519
  if (choices.isEmpty()) {
500
520
  return null
501
521
  }
502
- val filtered = choices.filter { it.width <= maxWidth && it.height <= maxHeight }
503
- val candidates = if (filtered.isNotEmpty()) filtered else choices.toList()
504
- return candidates.sortedBy { it.width * it.height }.last()
522
+ val maxCandidates = choices.filter { it.width <= maxWidth && it.height <= maxHeight }
523
+ val candidates = if (maxCandidates.isNotEmpty()) maxCandidates else choices.toList()
524
+
525
+ val ratioFiltered = if (targetRatio != null) {
526
+ candidates.filter { size ->
527
+ val ratio = if (targetRatio < 1f) {
528
+ size.height.toFloat() / size.width.toFloat()
529
+ } else {
530
+ size.width.toFloat() / size.height.toFloat()
531
+ }
532
+ kotlin.math.abs(ratio - targetRatio) <= 0.05f
533
+ }
534
+ } else {
535
+ emptyList()
536
+ }
537
+
538
+ val pickFrom = if (ratioFiltered.isNotEmpty()) ratioFiltered else candidates
539
+ return pickFrom.sortedBy { it.width * it.height }.last()
505
540
  }
506
541
 
507
542
  private fun startBackgroundThread() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "3.198.0",
3
+ "version": "3.200.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",