Swift 3 - 如何捕获图像及其子视图?

时间:2017-11-17 13:50:43

标签: ios swift avfoundation avcapturesession

我正在开发一个包含自定义相机视图的项目。我无法在主视图上捕获子视图。我的主视图由AVCaptureSession组成,我想拍摄superview和subview的照片单个图像。

我在代码中尝试的是什么:

class ViewController: UIViewController {

@IBOutlet weak var cameraButton: UIButton!

var captureSession = AVCaptureSession()

var backCamera: AVCaptureDevice?
var frontCamera: AVCaptureDevice?
var currentDevice: AVCaptureDevice?

var photoOutput: AVCapturePhotoOutput?

var cameraPreviewLayer:AVCaptureVideoPreviewLayer?

var image: UIImage?

var toggleCameraGestureRecognizer = UISwipeGestureRecognizer()

var zoomInGestureRecognizer = UISwipeGestureRecognizer()
var zoomOutGestureRecognizer = UISwipeGestureRecognizer()

override func viewDidLoad() {
    super.viewDidLoad()
    setupCaptureSession()
    setupDevice()
    setupInputOutput()
    setupPreviewLayer()
    captureSession.startRunning()

    toggleCameraGestureRecognizer.direction = .up
    toggleCameraGestureRecognizer.addTarget(self, action: #selector(self.switchCamera))
    view.addGestureRecognizer(toggleCameraGestureRecognizer)

    // Zoom In recognizer
    zoomInGestureRecognizer.direction = .right
    zoomInGestureRecognizer.addTarget(self, action: #selector(zoomIn))
    view.addGestureRecognizer(zoomInGestureRecognizer)

    // Zoom Out recognizer
    zoomOutGestureRecognizer.direction = .left
    zoomOutGestureRecognizer.addTarget(self, action: #selector(zoomOut))
    view.addGestureRecognizer(zoomOutGestureRecognizer)
    styleCaptureButton()
}
  cameraButton.layer.borderColor = UIColor.white.cgColor
    cameraButton.layer.borderWidth = 5
    cameraButton.clipsToBounds = true
    cameraButton.layer.cornerRadius = min(cameraButton.frame.width, cameraButton.frame.height) / 2
}

func setupCaptureSession() {
    captureSession.sessionPreset = AVCaptureSession.Preset.photo
}

func setupDevice() {
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
    let devices = deviceDiscoverySession.devices

    for device in devices {
        if device.position == AVCaptureDevice.Position.back {
            backCamera = device
        } else if device.position == AVCaptureDevice.Position.front {
            frontCamera = device
        }
    }
    currentDevice = backCamera
}

func setupInputOutput() {
    do {

        let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!)
        captureSession.addInput(captureDeviceInput)
        photoOutput = AVCapturePhotoOutput()
        photoOutput!.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey : AVVideoCodecType.jpeg])], completionHandler: nil)
        captureSession.addOutput(photoOutput!)


    } catch {
        print(error)
    }
}

func setupPreviewLayer() {
    self.cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    self.cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
    self.cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
    self.cameraPreviewLayer?.frame = view.frame

    self.view.layer.insertSublayer(self.cameraPreviewLayer!, at: 0)
}
@IBAction func cameraButton_TouchUpInside(_ sender: Any) {
    let settings = AVCapturePhotoSettings()
    self.photoOutput?.capturePhoto(with: settings, delegate: self)
}
}
extension ViewController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    if let imageData = photo.fileDataRepresentation() {
        self.image = UIImage(data: imageData)
        performSegue(withIdentifier: "Preview_Segue", sender: nil)
    }
}
}

请帮帮我

1 个答案:

答案 0 :(得分:1)

如果我理解你正在尝试获取相机抓取的内容(作为图像)和一些叠加视图。
据我所知,不可能抓住AVPreviewLayer内的内容,也许他们在最新版本中改变了一些东西。当我尝试(iOS6)时,它是不可能的,AVPreviewLayer区域始终为空。
你可以做的是拿走当前的相机缓冲区并在里面画画。通过将类设置为会话委托,您可以接收此回调可选

func captureOutput(_ output: AVCaptureOutput, 
                  didOutput sampleBuffer: CMSampleBuffer, 
                       from connection: AVCaptureConnection)

在这里,您将从相机接收图像,可以使用Accelerate框架或CoreImage将此缓冲区转换为图像。
不容易,但也不是impossible