一网通办ios
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

150 líneas
4.1 KiB

  1. //
  2. // CameraView.swift
  3. // im-client-ios
  4. //
  5. // Created by 北京居家科技有限公司 on 2022/3/10.
  6. //
  7. import SwiftUI
  8. import AVFoundation
  9. let cameraPreview = CameraPreview()
  10. fileprivate var captureSession = AVCaptureSession()
  11. fileprivate var videoDataOutput = AVCaptureVideoDataOutput()
  12. struct CameraPreviewHolder: ContentView{
  13. typealias NSViewType = CameraPreview
  14. func makeNSView(context: NSViewRepresentableContext<CameraPreviewHolder>) -> CameraPreview {
  15. let cameraPreview = CameraPreview()
  16. return cameraPreview
  17. }
  18. func updateNSView(_ nsView: CameraPreview, context: NSViewRepresentableContext<CameraPreviewHolder>) {
  19. }
  20. }
  21. final class CameraPreview: NSView {
  22. private var tmp:URL?
  23. init() {
  24. super.init(frame: .zero)
  25. var allowedAccess = false
  26. let blocker = DispatchGroup()
  27. blocker.enter()
  28. AVCaptureDevice.requestAccess(for: .video) { flag in
  29. allowedAccess = flag
  30. blocker.leave()
  31. }
  32. blocker.wait()
  33. guard allowedAccess else {
  34. print("No camera access")
  35. return
  36. }
  37. showCameraViewSeting()
  38. }
  39. func showCameraViewSeting() {
  40. let session = captureSession
  41. session.beginConfiguration()
  42. //分辨率
  43. session.sessionPreset = AVCaptureSession.Preset.high
  44. guard let videoDevice = AVCaptureDevice.default(for: .video) else {
  45. print("No video device")
  46. return
  47. }
  48. guard let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice),
  49. session.canAddInput(videoDeviceInput)
  50. else {
  51. print("Unable to determine video device input")
  52. return
  53. }
  54. session.addInput(videoDeviceInput)
  55. let videoOutput = videoDataOutput
  56. videoOutput.alwaysDiscardsLateVideoFrames = true
  57. if session.canAddOutput(videoOutput) {
  58. session.addOutput(videoOutput)
  59. }
  60. session.commitConfiguration()
  61. captureSession = session
  62. self.wantsLayer = true
  63. self.layer = AVCaptureVideoPreviewLayer()
  64. }
  65. required init?(coder: NSCoder) {
  66. fatalError("init(coder:) has not been implemented")
  67. }
  68. var videoPreviewLayer: AVCaptureVideoPreviewLayer {
  69. return self.layer as! AVCaptureVideoPreviewLayer
  70. }
  71. override func viewDidMoveToSuperview() { // on iOS .didMoveToSuperview
  72. super.viewDidMoveToSuperview()
  73. if nil != self.superview {
  74. self.videoPreviewLayer.session = captureSession
  75. self.videoPreviewLayer.videoGravity = .resizeAspect
  76. captureSession.startRunning()
  77. } else {
  78. captureSession.stopRunning()
  79. }
  80. }
  81. func scan(){
  82. videoDataOutput.setSampleBufferDelegate(cameraCaptureDelegate, queue: DispatchQueue.main)
  83. }
  84. func removeCameraPreview() {
  85. self.removeFromSuperview()
  86. }
  87. }
  88. class CameraCaptureDelegate: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate{
  89. func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
  90. let cgImage:CGImage = imageFromSampleBuffer(sampleBuffer: sampleBuffer)
  91. print("\(cgImage)")
  92. //获取的图片经过EFQRCode(GitHub上搜这个库)识别,如果含有二维码,即可识别出二维码数据
  93. // let result = EFQRCode.recognize(image: cgImage)
  94. // print("didOutput : \(String(describing: result))")
  95. }
  96. func captureOutput(_ output: AVCaptureOutput, didDrop sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
  97. print("didDrop sampleBuffer")
  98. }
  99. }
  100. func imageFromSampleBuffer(sampleBuffer: CMSampleBuffer) -> CGImage {
  101. let imageBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
  102. let ciImage : CIImage = CIImage(cvPixelBuffer: imageBuffer)
  103. let context:CIContext = CIContext.init(options: nil)
  104. let cgImage:CGImage = context.createCGImage(ciImage, from: ciImage.extent)!
  105. return cgImage
  106. }