Adding objects through viewing the camera in the application (Swift 3) not under the camera?

I have an inscription above the camera view, consisting of red circles stored in the Assets.xcasset ImgOverlay fill records, and the cameraview (preview) appears behind - or under - the overlay. It's great. As it should be. When I launch the application on the iPhone, the overlay appears as it should. See Img.1 But I also have a blue circle, which is under the camera view, and appears only if the camera view is missing. That is, disconnected or worked on the simulator. See Img.2 below.

Image 1. Red circles above camera view on iPhone

Image 2. Red circles, including the drawn blue circle in the simulator. The code that I have is here. I am doing something wrong, but I do not see it. I need the blue circle (s) visible on the iPhone, not just in the simulator. I'm trying to draw all the circles, so I can discard the red circles that are in a file like image.png. I prefer to draw circles for better accuracy on any device and display them instead of red circles, and then save the composite image, circles, and camera view. I have not yet been able to combine the images while saving, but getting the blue circle visible on the iPhone is the first step ... So it works almost completely. I do not see what I am doing wrong?

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 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. } 

}

0
source share
1 answer

You are very close ...

You have:

 @IBOutlet weak var shapeLayer: UIView! 

but then you also create a CAShapeLayer named shapeLayer:

 let shapeLayer = CAShapeLayer() 

which you add as a sublevel of your "main" view. Then you add all the rest on top of your main view, covering the shapeLayer.

In viewDidLoad (), change the section with the blue circle to the picture:

  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") //===================== 

Then, at the end of 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) 

See what you get :)

Edit: The next question moved to Combining Images in CameraView with Overlay. (Swift 3)?

+1
source

Source: https://habr.com/ru/post/1273951/


All Articles