【问题标题】:How to display live camera output in a UIView如何在 UIView 中显示实时摄像头输出
【发布时间】:2015-05-06 03:53:22
【问题描述】:

我想在视图控制器中显示实时摄像机输出。我开始with this example

这就是我所做的:我在故事板中创建了一个新的视图控制器并将其连接到下面的类。代码和输出如下。

import UIKit
import AVFoundation

//NOT WORKING - Unable to see Camera View in UIView: https://stackoverflow.com/questions/28683863/front-camera-to-fill-circular-uiview

class TestVC: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate{

var previewView : UIView!;
var boxView:UIView!;

//Camera Capture requiered properties
var videoDataOutput: AVCaptureVideoDataOutput!;
var videoDataOutputQueue : dispatch_queue_t!;
var previewLayer:AVCaptureVideoPreviewLayer!;
var captureDevice : AVCaptureDevice!
let session=AVCaptureSession();
var currentFrame:CIImage!
var done = false;


var cameraView = UIView()

override func viewDidLoad() {
    super.viewDidLoad()


    cameraView.frame = CGRectMake(100, self.view.center.y-260, 568, 568)
    cameraView.backgroundColor = UIColor(red:26/255, green:188/255, blue:156/255, alpha:1)
    cameraView.layer.cornerRadius = 284
    cameraView.layer.borderColor = UIColor.whiteColor().CGColor
    cameraView.layer.borderWidth = 15
    cameraView.contentMode = UIViewContentMode.ScaleToFill
    cameraView.layer.masksToBounds = true



    var screenSize = UIScreen.mainScreen().bounds.size;
    self.previewView = UIView(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height));
    self.previewView.contentMode = UIViewContentMode.ScaleAspectFit
    self.view.addSubview(previewView);

    //Add a box view
    self.boxView = UIView(frame: CGRectMake(0, 0, 100, 200));
    self.boxView.backgroundColor = UIColor.greenColor();
    self.boxView.alpha = 0.3;

    self.view.addSubview(self.boxView);

    self.setupAVCapture();
}

override func viewWillAppear(animated: Bool) {
    if !done {
        session.startRunning();
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

override func shouldAutorotate() -> Bool {
    if (UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.Unknown) {
            return false;
    }
    else {
        return true;
    }
}
}


// AVCaptureVideoDataOutputSampleBufferDelegate protocol and related methods
extension TestVC:  AVCaptureVideoDataOutputSampleBufferDelegate{

func setupAVCapture(){
    session.sessionPreset = AVCaptureSessionPreset640x480

    let devices = AVCaptureDevice.devices();
    // Loop through all the capture devices on this phone
    for device in devices {
        // Make sure this particular device supports video
        if (device.hasMediaType(AVMediaTypeVideo)) {
            // Finally check the position and confirm we've got the front camera
            if(device.position == AVCaptureDevicePosition.Front) {
                captureDevice = device as? AVCaptureDevice
                if captureDevice != nil {
                    beginSession()
                    break
                }
            }
        }
    }
}

func beginSession(){
    var err : NSError? = nil
    var deviceInput:AVCaptureDeviceInput = AVCaptureDeviceInput(device: captureDevice, error: &err)
    if err != nil {
        println("error: \(err?.localizedDescription)")
    }
    if self.session.canAddInput(deviceInput){
        self.session.addInput(deviceInput)
    }

    self.videoDataOutput = AVCaptureVideoDataOutput()
    var rgbOutputSettings = [NSNumber(integer: kCMPixelFormat_32BGRA):kCVPixelBufferPixelFormatTypeKey]
    self.videoDataOutput.alwaysDiscardsLateVideoFrames=true
    self.videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL)
    self.videoDataOutput.setSampleBufferDelegate(self, queue:self.videoDataOutputQueue)
    if session.canAddOutput(self.videoDataOutput){
        session.addOutput(self.videoDataOutput)
    }
    self.videoDataOutput.connectionWithMediaType(AVMediaTypeVideo).enabled = true

    self.previewLayer = AVCaptureVideoPreviewLayer(session: self.session)
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill

    var rootLayer :CALayer = self.cameraView.layer
    rootLayer.masksToBounds=true
    self.previewLayer.frame = rootLayer.bounds
    rootLayer.addSublayer(self.previewLayer)
    session.startRunning()

}

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {
    // do stuff here

}

// clean up AVCapture
func stopCamera(){
    session.stopRunning()
}

}

这就是我在输出中看到的全部内容:

来自the example,我不知道下面这段代码应该去哪里?所以,我把它放在viewDidLoad中。可能需要去其他地方吗?

    cameraView.frame = CGRectMake(100, self.view.center.y-260, 568, 568)
    cameraView.backgroundColor = UIColor(red:26/255, green:188/255, blue:156/255, alpha:1)
    cameraView.layer.cornerRadius = 284
    cameraView.layer.borderColor = UIColor.whiteColor().CGColor
    cameraView.layer.borderWidth = 15
    cameraView.contentMode = UIViewContentMode.ScaleToFill
    cameraView.layer.masksToBounds = true

【问题讨论】:

  • 无论您的代码是否有效,您都不会看到实时提要 - 模拟器无法使用摄像头。
  • 我在真机iPhone 5C上试了试,看到同样的绿框

标签: ios swift uiview uiviewcontroller ios-camera


【解决方案1】:

您要显示哪个UIView 的预览层? boxView 还是 cameraView?在您的代码中,您将预览层添加到cameraView,但您只将boxView 作为子视图添加到您的主视图中,因此永远不会显示cameraView

如果您想要cameraView,请将viewDidLoad 中的self.view.addSubview(self.boxView) 更改为self.view.addSubview(self.cameraView)。如果boxView,则将beginSession中的var rootLayer :CALayer = self.cameraView.layer更改为var rootLayer :CALayer = self.boxView.layer

无论哪种方式都会实时显示相机预览,尽管结果不同,因为boxViewcameraView 的设置不同。

我认为 boxView 是您想要的,所以 tl;dr:当您打算将预览层添加到 cameraView 时,您将其添加到 boxView

【讨论】:

    【解决方案2】:

    您已接近成功,但电线未插好。

    绿色框是boxview。如果您想在 boxview相机预览,您应该将 preview 添加到 boxview

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-02
      • 1970-01-01
      • 2011-11-06
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多