2017-03-03 53 views
0

我在由Assets.xcasset ImgOverlay佔位符存儲的紅色圓圈組成的攝像機視圖上覆蓋了一層,攝像機視圖(預覽)出現在疊加層之後或之下。沒關係。它應該是。 當我在iPhone上運行應用程序時,疊加層應該顯示。請參閱圖1 但我也繪製了一個藍色圓圈,即在相機視圖下方,並且僅在相機視圖丟失時纔會出現。即,關閉,或在模擬器上運行。參見下面的圖2。在應用程序(Swift 3)中的相機視圖中添加對象而不是在相機視圖下?

Image 1. red circles over camera view, in iPhone

Image 2. red circles including drawn blue circle in Simulator 我到目前爲止的代碼是在這裏。我做錯了什麼,但看不到它。我需要iPhone中可見的藍色圓圈,而不僅僅是模擬器。我試圖畫出所有的圈子,所以我可以放棄image.png類型文件中的紅色圓圈。我更喜歡在任何設備上繪製圓形以獲得更高的準確性,並顯示它們而不是紅色圓圈,然後保存合成圖像,圓形和相機視圖。我還沒有設法合併保存的圖像,但在iPhone上顯示藍色圓圈是第一步... 所以它幾乎完全工作。我看不到我做錯了什麼?

ViewController.swift

import UIKit 
import AVFoundation 
import Foundation 

class ViewController: UIViewController { 

@IBOutlet weak var navigationBar: UINavigationBar! 
@IBOutlet weak var imgOverlay: UIImageView! 
@IBOutlet weak var btnCapture: UIButton! 

@IBOutlet weak var shapeLayer: UIView! 

let captureSession = AVCaptureSession() 
let stillImageOutput = AVCaptureStillImageOutput() 
var previewLayer : AVCaptureVideoPreviewLayer? 

//var shapeLayer : CALayer? 

// If we find a device we'll store it here for later use 
var captureDevice : AVCaptureDevice? 

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

    let midX = self.view.bounds.midX 
    let midY = self.view.bounds.midY 

    let circlePath = UIBezierPath(arcCenter: CGPoint(x: midX,y: midY), radius: CGFloat(20), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true) 

    let shapeLayer = CAShapeLayer() 

    shapeLayer.path = circlePath.cgPath 
    //change the fill color 
    shapeLayer.fillColor = UIColor.clear.cgColor 
    //you can change the stroke color 
    shapeLayer.strokeColor = UIColor.blue.cgColor 
    //you can change the line width 
    shapeLayer.lineWidth = 2.5 

    view.layer.addSublayer(shapeLayer) 
    print("Shape layer drawn") 
    //===================== 
    captureSession.sessionPreset = AVCaptureSessionPresetHigh 

    if let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] { 
     // 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 back camera 
       if(device.position == AVCaptureDevicePosition.back) { 
        captureDevice = device 
        if captureDevice != nil { 
         print("Capture device found") 
         beginSession() 
        } 
       } 
      } 
     } 
    } 
} 

@IBAction func actionCameraCapture(_ sender: AnyObject) { 

    print("Camera button pressed") 
    saveToCamera() 
} 

func beginSession() { 

    do { 
     try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice)) 
     stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG] 

     if captureSession.canAddOutput(stillImageOutput) { 
      captureSession.addOutput(stillImageOutput) 
     } 

    } 
    catch { 
     print("error: \(error.localizedDescription)") 
    } 

    guard let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) else { 
     print("no preview layer") 
     return 
    } 
    // this is what displays the camera view. But - it's on TOP of the drawn view, and under the overview. ?? 
    self.view.layer.addSublayer(previewLayer) 
    previewLayer.frame = self.view.layer.frame 



    captureSession.startRunning() 
    print("Capture session running") 


    self.view.addSubview(navigationBar) 
    self.view.addSubview(imgOverlay) 
    self.view.addSubview(btnCapture) 
     } 

func saveToCamera() { 

    if let videoConnection = stillImageOutput.connection(withMediaType: AVMediaTypeVideo) { 
      stillImageOutput.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (CMSampleBuffer, Error) in 

      if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(CMSampleBuffer) { 
       if let cameraImage = UIImage(data: imageData) { 


        UIImageWriteToSavedPhotosAlbum(cameraImage, nil, nil, nil) 

       } 
      } 
     }) 
    } 
} 



override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

}

回答

1

你很接近......

您有:

@IBOutlet weak var shapeLayer: UIView! 

但你還可以創建一個名爲shapeLayer CAShapeLayer :

let shapeLayer = CAShapeLayer() 

您將其添加爲「主」視圖的子圖層。然後你添加其他所有的東西之上你的主視圖,覆蓋shapeLayer。

在viewDidLoad中(),你的藍圈,取出部分改成這樣:

let midX = self.view.bounds.midX 
    let midY = self.view.bounds.midY 

    let circlePath = UIBezierPath(arcCenter: CGPoint(x: midX,y: midY), radius: CGFloat(20), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true) 

    let shapeLayerPath = CAShapeLayer() 

    shapeLayerPath.path = circlePath.cgPath 
    //change the fill color 
    shapeLayerPath.fillColor = UIColor.clear.cgColor 
    //you can change the stroke color 
    shapeLayerPath.strokeColor = UIColor.blue.cgColor 
    //you can change the line width 
    shapeLayerPath.lineWidth = 2.5 

    // add the blue-circle layer to the shapeLayer ImageView 
    shapeLayer.layer.addSublayer(shapeLayerPath) 

    print("Shape layer drawn") 
    //===================== 

然後,在beginSession()結束......

self.view.addSubview(navigationBar) 
    self.view.addSubview(imgOverlay) 
    self.view.addSubview(btnCapture) 

    // shapeLayer ImageView is already a subview created in IB 
    // but this will bring it to the front 
    self.view.addSubview(shapeLayer) 

    // note: since these elements are added as @IBOutlet in IB, 
    // these could be: 

    // self.view.bringSubview(toFront: navigationBar) 
    // self.view.bringSubview(toFront: imgOverlay) 
    // self.view.bringSubview(toFront: btnCapture) 
    // self.view.bringSubview(toFront: shapeLayer) 

看看你會得到什麼:)

編輯:後續問題轉移到Combining Images in CameraView with Overlay. (Swift 3)?

+0

輝煌。謝謝,我接近不是我。現在,如果我可以保存結合了相機視圖和shapeLayer的完成圖像,我將是一個非常高興的人。 '打印(「按下相機按鈕」) saveToCamera()' 保存相機可以看到的圖像,但不保存圓圈疊加。 – Postmaster

+1

據我瞭解,堆棧溢出喜歡關於具體問題的問題,所以......如果您創建了一個關於合併和保存覆蓋的新問題,我也會給你一些幫助。 – DonMag

+0

好吧,我一直在努力嘗試解決這個問題很長時間 - 然後回來,看到你的回覆@DonMag。涼。發生新的問題。 – Postmaster