Camera problems on iPhone 7, dark photos

I have a controller that its functions are to open the front camera, show the instructions in the view with a guide for the user to place his face, draw two buttons to capture the selfie photo and cancel the process.

When capturing the photo with that controller, a function is called in a controller called ‘Service Manager’ to send the photo and update the stream’s lifecycle.

The problem occurs in devices like iPhone 7, when tapping on the “CAPTURE SELFIE” button the photo turns out to be dark or bright. Another problem that this driver has, but on all iOS devices, is that if the user minimizes the app and reopens it, the camera freezes and you have to minimize and reopen more than once to get the camera to work. resume and the user can capture the selfie correctly but the instructions are redrawn each time the user minimizes and opens the app again so the camera preview shows black.

What can be caused this?

I attached part of the code.

func setUpAVCapture() {
        session.sessionPreset = AVCaptureSession.Preset.hd1280x720
        guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: .video, position: AVCaptureDevice.Position.front) else { return }
        //        captureDevice = device
        //        self.beginSession()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        setNeedsStatusBarAppearanceUpdate()
        if previewLayer != nil {
            self.previewLayer?.frame = self.cameraPreview.layer.bounds
        }
         if AppConfig.shared.otorgante?.dataset != nil {
             for item in AppConfig.shared.otorgante!.dataset! {
                 if item.idCampo == "INTENTOS_VIDEO_TOKEN" {
                     self.intentosMaximos = Int(item.valor!)!
                 }
             }
         }
        
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        self.instructionsView!.removeFromSuperview()
        // Detener la sesión de captura cuando se sale de la vista
        self.stopCamera()
        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
            self.getFrame = false
        }
        
    }
    
    func stopCamera() {
        session.stopRunning()
    }
@objc func captureButtonTapped() {
        
        guard let captureSession = captureSession else { return }
        
        self.animacion?.isHidden = true
        blurView?.addBlurToView()
        
        if self.activityView == nil {
            activityView = UIView(frame: CGRect(x: (self.view.frame.width / 2) - 50, y: (self.view.frame.height / 2) - 50, width: 100, height: 100))
            activityView!.backgroundColor = UIColor(red:0 , green: 0, blue: 0, alpha: 0.8)
            activityView!.layer.cornerRadius = 4
            activityIndicator = UIActivityIndicatorView(frame: CGRect(x: (activityView!.frame.width / 2) - 15, y: (activityView!.frame.height / 2) - 15, width: 30, height: 30))
            if #available(iOS 13.0, *) {
                activityIndicator!.style = .large
                activityIndicator?.color = .white
            } else {
                activityIndicator?.style = .whiteLarge
            }
            activityView!.addSubview(activityIndicator!)
            self.view.addSubview(activityView!)
        }
        
        if intentosRealizados == 1 {
            if captureSession.canAddOutput(self.photoOutput) {
                captureSession.addOutput(self.photoOutput)
            }
        }
        
        let settings = AVCapturePhotoSettings()
        if let connection = photoOutput.connection(with: .video) {
            // Ajustar la orientación a vertical
            connection.videoOrientation = .portrait
        }
        
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let fileUrl = paths[0].appendingPathComponent("selfie.png")
        try? FileManager.default.removeItem(at: fileUrl)
        photoOutput.capturePhoto(with: settings, delegate: self)
        
        DispatchQueue.main.asyncAfter(deadline: .now() +  6.0){
            self.performSelector(onMainThread: #selector(self.stopSelfie), with: nil, waitUntilDone: false)
        }
        
        activityIndicator?.startAnimating()
        activityView?.isHidden = false
        
    }
    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        
       
        
        self.maskImage?.image = UIImage(named: "face_yellow")
        
        if let imageData = photo.fileDataRepresentation(), let image = UIImage(data: imageData) {
            
            let compressedData = image.jpegData(compressionQuality: 0.5)
            if let compressedImage = UIImage(data: compressedData ?? Data()){
                
                if let compressedData = compressImage(image: compressedImage, maxSizeInBytes: 1 * 1024 * 1024) {
                    
                    
                    let rotatedImage = UIImage(data: compressedData)?.rotate(radians: .pi / 0.5)
                    let pngData = rotatedImage?.jpegData(compressionQuality: 1.0)
                    
                    let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
                    let fileURL = documentDirectory.appendingPathComponent("selfie.png")
                    if let data = pngData {
                       
                       
                        do {
                            
                            try data.write(to: fileURL)
                            //print("Se guardó la imagen en: \(fileURL)")
                            
                            
                        } catch {
                            
                            //print("Error al guardar la imagen: \(error.localizedDescription)")
                        }
                    }
                }
            }
            
        }
        
    }
   func compressImage(image: UIImage, maxSizeInBytes: Int) -> Data? {
        let maxHeight: CGFloat = 1024.0
        let maxWidth: CGFloat = 1024.0
        
        var actualWidth = image.size.width
        var actualHeight = image.size.height
        
        if actualWidth <= maxWidth && actualHeight <= maxHeight {
            return image.jpegData(compressionQuality: 1.0)
        }
        
        let imgRatio = actualWidth / actualHeight
        var newWidth: CGFloat
        var newHeight: CGFloat
        
        if imgRatio > maxWidth / maxHeight {
            newWidth = maxWidth
            newHeight = maxWidth / imgRatio
        } else {
            newHeight = maxHeight
            newWidth = maxHeight * imgRatio
        }
        
        let renderRect = CGRect(x: 0, y: 0, width: newWidth, height: newHeight)
        
        let renderer = UIGraphicsImageRenderer(size: renderRect.size)
        let compressedImage = renderer.image { context in
            image.draw(in: renderRect)
        }
        
        var compressionQuality: CGFloat = 1.0
        var finalImageData = compressedImage.jpegData(compressionQuality: compressionQuality)
        
        while finalImageData?.count ?? 0 > maxSizeInBytes && compressionQuality > 0.1 {
            compressionQuality -= 0.1
            finalImageData = compressedImage.jpegData(compressionQuality: compressionQuality)
        }
        
        return finalImageData
    }

That the use of the camera, in the application, is compatible with all devices from iPhone 6+.
The intention of this controller is that the application takes a selfie photo, saves it in png and that the file size is less than 5MB.
Thank you

This topic was automatically closed after 166 days. New replies are no longer allowed.