react-native-rectangle-doc-scanner 1.9.0 → 1.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.
@@ -262,10 +262,9 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
262
262
  effectiveObservation = nil
263
263
  }
264
264
 
265
- let shouldDisplayOverlay = currentStableCounter > 0 && effectiveObservation != nil
266
- updateNativeOverlay(with: shouldDisplayOverlay ? effectiveObservation : nil)
267
-
265
+ let overlayStableThreshold = max(2, Int(truncating: detectionCountBeforeCapture) / 2)
268
266
  let payload: [String: Any?]
267
+
269
268
  if let observation = effectiveObservation {
270
269
  let points = [
271
270
  pointForOverlay(from: observation.topLeft, frameSize: frameSize),
@@ -275,6 +274,13 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
275
274
  ]
276
275
 
277
276
  currentStableCounter = min(currentStableCounter + 1, Int(truncating: detectionCountBeforeCapture))
277
+
278
+ let normalizedArea = observation.boundingBox.width * observation.boundingBox.height
279
+ let meetsArea = normalizedArea >= 0.06 && normalizedArea <= 0.95
280
+ let meetsConfidence = observation.confidence >= 0.65
281
+ let shouldDisplayOverlay = currentStableCounter >= overlayStableThreshold && meetsArea && meetsConfidence
282
+ updateNativeOverlay(with: shouldDisplayOverlay ? observation : nil)
283
+
278
284
  payload = [
279
285
  "rectangleCoordinates": [
280
286
  "topLeft": ["x": points[0].x, "y": points[0].y],
@@ -288,6 +294,7 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
288
294
  ]
289
295
  } else {
290
296
  currentStableCounter = 0
297
+ updateNativeOverlay(with: nil)
291
298
  payload = [
292
299
  "rectangleCoordinates": NSNull(),
293
300
  "stableCounter": currentStableCounter,
@@ -312,6 +319,7 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
312
319
  self.gridLayer.path = nil
313
320
  self.outlineLayer.isHidden = true
314
321
  self.gridLayer.isHidden = true
322
+ self.smoothedOverlayPoints = nil
315
323
  return
316
324
  }
317
325
 
@@ -326,13 +334,15 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
326
334
  self.convertToLayerPoint(observation.bottomLeft, previewLayer: previewLayer),
327
335
  ]
328
336
 
337
+ let orderedPoints = self.orderPoints(rawPoints)
338
+
329
339
  let points: [CGPoint]
330
340
  if let previous = self.smoothedOverlayPoints, previous.count == 4 {
331
- points = zip(previous, rawPoints).map { prev, next in
332
- CGPoint(x: prev.x * 0.7 + next.x * 0.3, y: prev.y * 0.7 + next.y * 0.3)
341
+ points = zip(previous, orderedPoints).map { prev, next in
342
+ CGPoint(x: prev.x * 0.85 + next.x * 0.15, y: prev.y * 0.85 + next.y * 0.15)
333
343
  }
334
344
  } else {
335
- points = rawPoints
345
+ points = orderedPoints
336
346
  }
337
347
 
338
348
  self.smoothedOverlayPoints = points
@@ -376,6 +386,37 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
376
386
  CGPoint(x: start.x + (end.x - start.x) * t, y: start.y + (end.y - start.y) * t)
377
387
  }
378
388
 
389
+ private func orderPoints(_ points: [CGPoint]) -> [CGPoint] {
390
+ guard points.count == 4 else { return points }
391
+
392
+ let center = points.reduce(CGPoint.zero) { partial, point in
393
+ CGPoint(x: partial.x + point.x / 4.0, y: partial.y + point.y / 4.0)
394
+ }
395
+
396
+ let angles = points.map { point -> (CGPoint, CGFloat) in
397
+ let angle = atan2(point.y - center.y, point.x - center.x)
398
+ return (point, angle)
399
+ }
400
+
401
+ let sorted = angles.sorted { $0.1 < $1.1 }.map { $0.0 }
402
+
403
+ var startIndex = 0
404
+ for index in 1..<sorted.count {
405
+ let candidate = sorted[index]
406
+ let current = sorted[startIndex]
407
+ if candidate.y < current.y || (candidate.y == current.y && candidate.x < current.x) {
408
+ startIndex = index
409
+ }
410
+ }
411
+
412
+ return [
413
+ sorted[startIndex % 4],
414
+ sorted[(startIndex + 1) % 4],
415
+ sorted[(startIndex + 2) % 4],
416
+ sorted[(startIndex + 3) % 4],
417
+ ]
418
+ }
419
+
379
420
  // MARK: - Capture
380
421
 
381
422
  func capture(completion: @escaping (Result<RNRDocScannerCaptureResult, Error>) -> Void) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "1.9.0",
3
+ "version": "1.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",