react-native-rectangle-doc-scanner 4.8.0 → 4.10.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.
@@ -209,12 +209,30 @@ class CameraController(
209
209
  ?: return
210
210
  sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0
211
211
 
212
- val viewAspect = if (previewView.height == 0) {
213
- 1.0
212
+ // Calculate view aspect ratio considering sensor orientation
213
+ // For portrait mode with 90/270 degree sensor, we need to swap width/height
214
+ val displayRotation = displayRotationDegrees()
215
+ val totalRotation = if (useFrontCamera) {
216
+ (sensorOrientation + displayRotation) % 360
214
217
  } else {
215
- previewView.width.toDouble() / previewView.height.toDouble()
218
+ (sensorOrientation - displayRotation + 360) % 360
216
219
  }
217
220
 
221
+ val viewWidth = previewView.width.takeIf { it > 0 } ?: 1200
222
+ val viewHeight = previewView.height.takeIf { it > 0 } ?: 1928
223
+
224
+ // If total rotation is 90 or 270, the sensor output is rotated, so we need to match against swapped aspect
225
+ val viewAspect = if (totalRotation == 90 || totalRotation == 270) {
226
+ // Sensor outputs landscape (e.g., 1920x1080), but we display portrait
227
+ // So we want to find sensor size with aspect ~= viewHeight/viewWidth
228
+ viewHeight.toDouble() / viewWidth.toDouble()
229
+ } else {
230
+ viewWidth.toDouble() / viewHeight.toDouble()
231
+ }
232
+
233
+ Log.d(TAG, "[CAMERA2] sensorOrientation=$sensorOrientation displayRotation=$displayRotation totalRotation=$totalRotation")
234
+ Log.d(TAG, "[CAMERA2] viewAspect=$viewAspect (view: ${viewWidth}x${viewHeight})")
235
+
218
236
  val previewSizes = streamConfigMap.getOutputSizes(SurfaceTexture::class.java)
219
237
  previewSize = chooseBestSize(previewSizes, viewAspect, null, preferClosestAspect = true)
220
238
 
@@ -171,10 +171,10 @@ class DocumentDetector {
171
171
  }
172
172
 
173
173
  // Apply a light blur to reduce noise without killing small edges.
174
- Imgproc.GaussianBlur(grayMat, blurredMat, Size(3.0, 3.0), 0.0)
174
+ Imgproc.GaussianBlur(grayMat, blurredMat, Size(5.0, 5.0), 0.0)
175
175
 
176
- // Apply Canny edge detection with lower thresholds for small, low-contrast documents.
177
- Imgproc.Canny(blurredMat, cannyMat, 40.0, 120.0)
176
+ // Apply Canny edge detection with lower thresholds for better corner detection.
177
+ Imgproc.Canny(blurredMat, cannyMat, 30.0, 90.0)
178
178
  val kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, Size(3.0, 3.0))
179
179
  Imgproc.morphologyEx(cannyMat, morphMat, Imgproc.MORPH_CLOSE, kernel)
180
180
  kernel.release()
@@ -188,12 +188,13 @@ class DocumentDetector {
188
188
  Point(rectangle.bottomLeft.x.coerceIn(0.0, maxX), rectangle.bottomLeft.y.coerceIn(0.0, maxY)),
189
189
  Point(rectangle.bottomRight.x.coerceIn(0.0, maxX), rectangle.bottomRight.y.coerceIn(0.0, maxY))
190
190
  )
191
- val criteria = TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER, 30, 0.01)
191
+ // Use larger window for better sub-pixel corner refinement (matching iOS high accuracy)
192
+ val criteria = TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER, 40, 0.001)
192
193
  return try {
193
194
  Imgproc.cornerSubPix(
194
195
  gray,
195
196
  points,
196
- Size(5.0, 5.0),
197
+ Size(11.0, 11.0), // Increased from 5x5 to 11x11 for better accuracy
197
198
  Size(-1.0, -1.0),
198
199
  criteria
199
200
  )
@@ -227,11 +228,13 @@ class DocumentDetector {
227
228
  val approx = MatOfPoint2f()
228
229
  val contour2f = MatOfPoint2f(*contour.toArray())
229
230
  val arcLength = Imgproc.arcLength(contour2f, true)
230
- val epsilon = 0.018 * arcLength
231
+ // Reduced epsilon for more accurate corner detection (matching iOS high accuracy)
232
+ val epsilon = 0.01 * arcLength
231
233
  Imgproc.approxPolyDP(contour2f, approx, epsilon, true)
232
234
  val relaxed = if (approx.total() != 4L) {
233
235
  MatOfPoint2f().apply {
234
- Imgproc.approxPolyDP(contour2f, this, 0.03 * arcLength, true)
236
+ // Reduced fallback epsilon for better corner accuracy
237
+ Imgproc.approxPolyDP(contour2f, this, 0.02 * arcLength, true)
235
238
  }
236
239
  } else {
237
240
  null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "4.8.0",
3
+ "version": "4.10.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",