相机已经运行怎么拍照

How can I take picture when the camera is already running

我有一个应用程序有一个 snapchat 类型的相机,其中 UIView 显示后置相机。我在顶部有一个按钮,当我单击该按钮时,我想拍照。现在,当我单击该按钮时,它只会打开另一个摄像头。

这是点击按钮的代码:

@IBAction func takePhoto(_ sender: UIButton) {
    imagePicker =  UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = .camera
    present(imagePicker, animated: true, completion: nil)
}

但是,如上所述,这是多余的,因为我的 ViewController 在 ViewDidAppear 上显示了一个摄像头。

override func viewDidAppear(_ animated: Bool) {
    self.ShowCamera(self.frontCamera)
    fullView.isHidden = false
}

func ShowCamera(_ front: Bool) {
    self.captureSession.sessionPreset = AVCaptureSession.Preset.photo

    if let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [ .builtInWideAngleCamera,.builtInMicrophone],
                                                                mediaType: AVMediaType.video, position: .back).devices.first {
        self.captureDevice = availableDevices
        if captureSession.isRunning != true {
            self.beginSession()
        }
    }

    if self.captureDevice == nil {
        print("capture device is nil")
        return
    }

    do {
        try self.captureSession.removeInput(AVCaptureDeviceInput(device: self.captureDevice!))
    } catch let error as NSError {
        print(error)
    }
}

func beginSession() {
    do {
        let captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice)
        captureSession.addInput(captureDeviceInput)
    } catch {
        print(error.localizedDescription)
    }

    captureSession.startRunning()

    let preview = AVCaptureVideoPreviewLayer(session: captureSession)
    self.previewLayer = preview
    preview.videoGravity = AVLayerVideoGravity.resizeAspectFill
    CameraView.layer.insertSublayer(self.previewLayer, at: 0)
    self.previewLayer.frame = self.CameraView.layer.frame

    let dataOutput = AVCaptureVideoDataOutput()
    dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString) : NSNumber(value: kCVPixelFormatType_32BGRA)] as [String : Any]
    dataOutput.alwaysDiscardsLateVideoFrames = true

    if captureSession.canAddOutput(dataOutput)
    {
        captureSession.addOutput(dataOutput)
    }

    captureSession.commitConfiguration()
}

上面的所有代码只是获取 UIView 并显示相机。 TakePhoto 按钮是显示在相机图像顶部的子层。当我单击该按钮时,我想使用相机上显示的任何图像。

从 运行 会话中捕获照片的命令是

guard let output = captureSession.outputs[0] as? AVCapturePhotoOutput 
else {return}
output.capturePhoto(with: settings, delegate: self)

这里,self,是一个AVCapturePhotoCaptureDelegate。然后您通过委托消息接收照片并提取并保存它。