【问题标题】:Change location of UIView within captureOutput在 captureOutput 中更改 UIView 的位置
【发布时间】:2017-02-03 23:19:14
【问题描述】:

目前,我在我的 Swift 应用程序中运行了一个 AVCaptureSession,并且我有一个带有 CGRect 的 UIView,我想在相机源上移动它。我一直在尝试通过更改 captureOutput 函数中的坐标来更新 UIView 框架的位置,但是当我更改它们时,它们并没有更新。更改 UIView 位置以使其即时更新的正确方法是什么?

这是进行捕获会话的代码部分:

class CameraViewController: UIViewController, UIImagePickerControllerDelegate, AVCaptureVideoDataOutputSampleBufferDelegate

{

@IBOutlet weak var cameraView: UIImageView!
var rectangleView : UIView!
var captureSession : AVCaptureSession?
var previewLayer : AVCaptureVideoPreviewLayer?
var rect = CGRect(x: 150, y: 150, width: 50, height: 50)
var xCoord: Float = 0.0

override func viewDidLoad() {
    super.viewDidLoad()

    //---editing rectangle view---
    rectangleView = UIView()
    rectangleView.layer.borderColor = UIColor(hue: 0.2444, saturation: 1, brightness: 0.96, alpha: 1).cgColor
    rectangleView.layer.borderWidth = 50;
    rectangleView.tag = 1
    self.view.addSubview(rectangleView)
    //----------------------------


    captureSession = AVCaptureSession()
    captureSession?.sessionPreset = AVCaptureSessionPreset1920x1080

    let backCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    var input = AVCaptureDeviceInput()
    do{
        input = try AVCaptureDeviceInput(device: backCamera)
    }catch{
        print("Error finding back Camera")
    }
    var error : NSError?

    if (error == nil && (captureSession?.canAddInput(input))!)
    {
        captureSession?.addInput(input)

        let dataOutput = AVCaptureVideoDataOutput()
        dataOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "string buffer delegate"))

        if (captureSession?.canAddOutput(dataOutput))!
        {

            captureSession?.addOutput(dataOutput)
            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
            //                cameraView.layer.addSublayer(previewLayer!)
            self.view.layer.addSublayer(previewLayer!)
            self.view.bringSubview(toFront: rectangleView)
            previewLayer?.frame = self.view.bounds
            rectangleView.frame = rect
            captureSession?.startRunning()

        }
    }
}

这里是 captureOutput 函数: setY 方法是 UIView 类的扩展,可以改变框架的 y 坐标。

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {

    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer!)
    let x = rectangleView.frame.origin.x
    let y = rectangleView.frame.origin.y - 1
    let height = rectangleView.frame.size.height
    let width = rectangleView.frame.size.width

    rectangleView.setY(y: y)

    print(rectangleView.frame.origin.y)

    //*** Making UIImage out of pixelBuffer ****
    let ciImage = CIImage(cvPixelBuffer: pixelBuffer!)
    let pixelBufferWidth = CGFloat(CVPixelBufferGetWidth(pixelBuffer!))
    let pixelBufferHeight = CGFloat(CVPixelBufferGetHeight(pixelBuffer!))
    let imageRect:CGRect = CGRect(x: 0,y: 0,width: pixelBufferWidth, height: pixelBufferHeight)
    let ciContext = CIContext.init()
    let cgimage = ciContext.createCGImage(ciImage, from: imageRect )
    let image = UIImage(cgImage: cgimage!)
    //******************************************



}

感谢您的帮助,

-nfarrell

【问题讨论】:

  • 你能分享你的代码吗?
  • 是的,我现在就编辑它。
  • 你试过在主线程调用setY(y:)方法吗? DispatchQueue.main.async { self.rectangleView.setY(y: y) }。 (我假设您已经在此方法之外测试了 setY 方法并确认它按预期工作)
  • 非常好的建议,感谢您的修复。我是stackoverflow的新手。无论如何我可以给你投赞成票或帮助我吗?
  • 我会将我的评论添加为答案,您可以接受并点赞。 :)

标签: ios swift uiview avfoundation


【解决方案1】:

您需要在主线程上调用 setY(y:) 方法,因为它正在操作 UI:

DispatchQueue.main.async {
    self.rectangleView.setY(y: y)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    相关资源
    最近更新 更多