Захватывать только камеры в AVCapture Swift - PullRequest
0 голосов
/ 25 января 2019

вот мой код

import UIKit
import AVFoundation

class ViewController: UIViewController {

    @IBOutlet weak var cameraView: UIView!

    var image: UIImage!

    var captureSession = AVCaptureSession()
    var backCamera: AVCaptureDevice?
    var frontCamera: AVCaptureDevice?
    var currentCamera: AVCaptureDevice?

    var photoOutput: AVCapturePhotoOutput?

    var cameraPreviewLayer: AVCaptureVideoPreviewLayer?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.


    }

    override func viewDidAppear(_ animated: Bool) {

        setupCaptureSession()
        setupDevice()
        setupInputOutput()
        setupPreviewLayer()
        startRunningCaptureSession()

    }

    @IBAction func cameraButton_Tab(_ sender: Any) {

        let settings = AVCapturePhotoSettings()

//        performSegue(withIdentifier: "showPhoto_Segue", sender: nil)
        photoOutput?.capturePhoto(with: settings, delegate: self)

    }

    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

            }

        }

        currentCamera = backCamera

    }

    func setupInputOutput() {

        do{

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

        }catch {
            print(error)
        }

    }

    func setupPreviewLayer() {

        cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
        cameraPreviewLayer!.frame = self.cameraView.bounds
        self.cameraView.layer.insertSublayer(cameraPreviewLayer!, at: 0)

    }

    func startRunningCaptureSession() {

        captureSession.startRunning()

    }

}

extension ViewController: AVCapturePhotoCaptureDelegate {

    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        if let imageData = photo.fileDataRepresentation(){
            image = UIImage(data: imageData)

        }
    }

}

enter image description here

см. Изображение, Я хочу сохранить изображение, цвет фона которого желтый Я могу видеть камеру через это

Но я сохраняю изображение, похоже, что сохраняю весь вид, а не квадрат.

Я делаю UIImageView одинакового размера с желтым UIView и сохраняю вывод, требуется захват всего изображения и изменение его размера.

Как изменить прямоугольник на квадрат с помощью сжатия

Как я могу поймать только желтый фон и сохранить его?

1 Ответ

0 голосов
/ 25 января 2019

Это didFinishProcessingPhoto вернет полное изображение, как то, что видит камера.Вы не увидите изображение, которое отображается в вашем PreviewLayer.Таким образом, чтобы получить UIImage из показанных PreviewLayer, вы можете изменить размер захваченного изображения.

Что ж, изменить размер можно также двумя способами: один с сохранением соотношения сторон, а другой - с передачей точногоразмер.Я бы порекомендовал использовать соотношение сторон, потому что оно гарантирует, что ваше изображение не будет сжиматься или растягиваться при любом размере, а пропуск неправильного размера не сможет удовлетворить ваши требования.

Изменить размер UIImage передача нового CGSize:

extension UIImage {
    func scaleImage(toSize newSize: CGSize) -> UIImage? {
        var newImage: UIImage?
        let newRect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height).integral
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
        if let context = UIGraphicsGetCurrentContext(), let cgImage = self.cgImage {
            context.interpolationQuality = .high
            let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newSize.height)
            context.concatenate(flipVertical)
            context.draw(cgImage, in: newRect)
            if let img = context.makeImage() {
                newImage = UIImage(cgImage: img)
            }
            UIGraphicsEndImageContext()
        }
        return newImage
    }
}

Использование: capturedImage.scaleImage(toSize: CGSize(width: 300, height: 300))

Изменение размера UIImage с сохранением соотношения сторон:

extension UIImage {
    func scaleImage(toWidth newWidth: CGFloat) -> UIImage {
        let scale = newWidth / self.size.width
        let newHeight = self.size.height * scale
        let newSize = CGSize(width: newWidth, height: newHeight)

        let renderer = UIGraphicsImageRenderer(size: newSize)

        let image = renderer.image { (context) in
            self.draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize))
        }
        return image
    }
}

Использование: capturedImage.scaleImage(toWidth: 300)

Ссылка: Изменить размер UIImage до 200x200pt / px

Обновление:

Сохраните приведенный ниже метод, как в вашем коде:

@IBAction func cameraButton_Tab(_ sender: Any) {
    let settings = AVCapturePhotoSettings()
    photoOutput?.capturePhoto(with: settings, delegate: self)
}

extension ViewController: AVCapturePhotoCaptureDelegate {

    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        if let imageData = photo.fileDataRepresentation(){
            let capturedImage = UIImage(data: imageData)
            let cropImage = capturedImage.scaleImage(toWidth: cameraPreviewLayer!.frame.size.width) //It will return the Image size of Camera Preview
        }
    }
}
...