2017-02-03 2 views
1

В настоящее время у меня есть AVCaptureSession, работающий в моем приложении Swift, и у меня есть UIView с CGRect, который я хочу перемещать по каналу камеры. Я пытался обновить местоположение фрейма UIView, изменив координаты в функции captureOutput, но по мере их изменения они не обновляются. Каков правильный способ изменения местоположения UIView, чтобы он обновлялся «на лету»?Изменить местоположение UIView в пределах captureOutput

Вот часть кода, где производится сеанс захвата:

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

+0

Можете ли вы поделиться вашей код? –

+0

Yup Я сейчас отредактирую. – NFarrell

+0

Вы пробовали вызывать метод setY (y:) 'в основном потоке? 'DispatchQueue.main.async {self.rectangleView.setY (y: y)}'. (Я предполагаю, что вы протестировали метод 'setY' за пределами этого метода и подтвердили, что он работает так, как ожидалось). –

ответ

0

Вам нужно вызвать метод setY(y:) в основном потоке, так как он манипулирует интерфейс:

DispatchQueue.main.async { 
    self.rectangleView.setY(y: y) 
} 
Смежные вопросы