【问题标题】:Adding objects over camera view in app (Swift 3) not under camera view?在应用程序(Swift 3)中的相机视图上添加对象而不是在相机视图下?
【发布时间】:2017-03-03 12:59:59
【问题描述】:

我在由红色圆圈组成的相机视图上有一个叠加层,存储在 Assets.xcasset ImgOverlay 占位符中,并且相机视图(预览)出现在叠加层的后面或下方。没关系。应该如此。 当我在 iPhone 上运行该应用程序时,叠加层会按原样显示。参见图 1 但我也绘制了一个蓝色圆圈,即在相机视图下方,只有在相机视图丢失时才会出现。即关闭,或在模拟器上运行。请参见下面的图 2。

图片 1. iPhone 中相机视图上方的红色圆圈

图 2. 模拟器中的红色圆圈,包括绘制的蓝色圆圈
我到目前为止的代码在这里。我做错了什么,但看不到。我需要在 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.
}

}

【问题讨论】:

    标签: ios swift3 camera-overlay


    【解决方案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)?

    【讨论】:

    • 太棒了。谢谢,我不是很接近。现在,如果我可以保存结合了相机视图和 shapeLayer 的完成图像,我将是一个非常快乐的人。 'print(“按下相机按钮”)saveToCamera()'部分保存相机可以看到的图像,但不保存圆圈的覆盖。
    • 据我了解,Stack Overflow 喜欢与特定问题相关的问题,所以... .
    • 好的,我多年来一直在努力解决这个问题 - 然后回来看到你的回复@DonMag。凉爽的。新问题出现了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多