react-native-rectangle-doc-scanner 1.8.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.
- package/ios/RNRDocScannerView.swift +56 -3
- package/package.json +1 -1
|
@@ -262,9 +262,9 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
|
|
|
262
262
|
effectiveObservation = nil
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
let overlayStableThreshold = max(2, Int(truncating: detectionCountBeforeCapture) / 2)
|
|
267
266
|
let payload: [String: Any?]
|
|
267
|
+
|
|
268
268
|
if let observation = effectiveObservation {
|
|
269
269
|
let points = [
|
|
270
270
|
pointForOverlay(from: observation.topLeft, frameSize: frameSize),
|
|
@@ -274,6 +274,13 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
|
|
|
274
274
|
]
|
|
275
275
|
|
|
276
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
|
+
|
|
277
284
|
payload = [
|
|
278
285
|
"rectangleCoordinates": [
|
|
279
286
|
"topLeft": ["x": points[0].x, "y": points[0].y],
|
|
@@ -287,6 +294,7 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
|
|
|
287
294
|
]
|
|
288
295
|
} else {
|
|
289
296
|
currentStableCounter = 0
|
|
297
|
+
updateNativeOverlay(with: nil)
|
|
290
298
|
payload = [
|
|
291
299
|
"rectangleCoordinates": NSNull(),
|
|
292
300
|
"stableCounter": currentStableCounter,
|
|
@@ -311,6 +319,7 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
|
|
|
311
319
|
self.gridLayer.path = nil
|
|
312
320
|
self.outlineLayer.isHidden = true
|
|
313
321
|
self.gridLayer.isHidden = true
|
|
322
|
+
self.smoothedOverlayPoints = nil
|
|
314
323
|
return
|
|
315
324
|
}
|
|
316
325
|
|
|
@@ -318,13 +327,26 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
|
|
|
318
327
|
return
|
|
319
328
|
}
|
|
320
329
|
|
|
321
|
-
let
|
|
330
|
+
let rawPoints = [
|
|
322
331
|
self.convertToLayerPoint(observation.topLeft, previewLayer: previewLayer),
|
|
323
332
|
self.convertToLayerPoint(observation.topRight, previewLayer: previewLayer),
|
|
324
333
|
self.convertToLayerPoint(observation.bottomRight, previewLayer: previewLayer),
|
|
325
334
|
self.convertToLayerPoint(observation.bottomLeft, previewLayer: previewLayer),
|
|
326
335
|
]
|
|
327
336
|
|
|
337
|
+
let orderedPoints = self.orderPoints(rawPoints)
|
|
338
|
+
|
|
339
|
+
let points: [CGPoint]
|
|
340
|
+
if let previous = self.smoothedOverlayPoints, previous.count == 4 {
|
|
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)
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
points = orderedPoints
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
self.smoothedOverlayPoints = points
|
|
349
|
+
|
|
328
350
|
let outline = UIBezierPath()
|
|
329
351
|
outline.move(to: points[0])
|
|
330
352
|
outline.addLine(to: points[1])
|
|
@@ -364,6 +386,37 @@ class RNRDocScannerView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate, A
|
|
|
364
386
|
CGPoint(x: start.x + (end.x - start.x) * t, y: start.y + (end.y - start.y) * t)
|
|
365
387
|
}
|
|
366
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
|
+
|
|
367
420
|
// MARK: - Capture
|
|
368
421
|
|
|
369
422
|
func capture(completion: @escaping (Result<RNRDocScannerCaptureResult, Error>) -> Void) {
|