react-native-vision-camera/package/ios/Core/CameraSession+CodeScanner.swift

106 lines
2.7 KiB
Swift
Raw Normal View History

//
// CameraSession+CodeScanner.swift
// VisionCamera
//
// Created by Marc Rousavy on 11.10.23.
// Copyright © 2023 mrousavy. All rights reserved.
//
import AVFoundation
import Foundation
extension CameraSession: AVCaptureMetadataOutputObjectsDelegate {
public func metadataOutput(_: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from _: AVCaptureConnection) {
guard let onCodeScanned = delegate?.onCodeScanned else {
// No delegate callback
return
}
guard !metadataObjects.isEmpty else {
// No codes detected
return
}
guard let device = videoDeviceInput?.device else {
// No cameraId set
return
}
let size = device.activeFormat.videoDimensions
// Map codes to JS values
let codes = metadataObjects.map { object in
var value: String?
var corners: [CGPoint]?
if let code = object as? AVMetadataMachineReadableCodeObject {
value = code.stringValue
corners = code.corners.map {
CGPoint(x: $0.x * Double(size.width), y: $0.y * Double(size.height))
}
}
let x = object.bounds.origin.x * Double(size.width)
let y = object.bounds.origin.y * Double(size.height)
let w = object.bounds.width * Double(size.width)
let h = object.bounds.height * Double(size.height)
let frame = CGRect(x: x, y: y, width: w, height: h)
return Code(type: object.type, value: value, frame: frame, corners: corners)
}
// Call delegate (JS) event
onCodeScanned(codes, CodeScannerFrame(width: size.width, height: size.height))
}
/**
A scanned QR/Barcode.
*/
struct Code {
/**
Type of the scanned Code
*/
let type: AVMetadataObject.ObjectType
/**
Decoded value of the code
*/
let value: String?
/**
Location of the code on-screen, relative to the video output layer
*/
let frame: CGRect
/**
Location of the code on-screen, relative to the video output layer
*/
let corners: [CGPoint]?
/**
Converts this Code to a JS Object (Dictionary)
*/
func toJSValue() -> [String: AnyHashable] {
return [
"type": type.descriptor,
"value": value,
"frame": [
"x": frame.origin.x,
"y": frame.origin.y,
"width": frame.size.width,
"height": frame.size.height,
],
"corners": corners?.map { [
"x": $0.x,
"y": $0.y,
] } ?? [],
]
}
}
struct CodeScannerFrame {
let width: Int32
let height: Int32
func toJSValue() -> [String: AnyHashable] {
return [
"width": width,
"height": height,
]
}
}
}