0
votes

L'image de l'iphone capturée à partir de la caméra tourne automatiquement Swift

Par programme, j'ai capturé une image de mon appareil photo dans mon application. Il a été bien récupéré, mais lorsque je passe à un autre, affichez et rejetez cette vue à ce moment-là, mon image veut pivoter en paysage. J'ai capturé des images de la caméra. Lorsque je récupère l'image de la photothèque, aucun problème n'a été détecté.

L'image suivante est mon image d'origine. Capture d'écran

Et je veux faire pivoter l'image . Capture d'écran

Code ci-dessous: strong >

UIImage(cgImage: tempImageHolder.cgImage!, scale: tempImageHolder.scale, orientation: .up)

Lors de la prise d'images à partir du paysage de gauche:

Entrée: Capture d'écran

Sortie: Capture d'écran

Lors de la prise d'images à partir du paysage de droite

Entrée: Capture d'écran

Résultat: Capture d'écran

var captureSesssion : AVCaptureSession!
var cameraOutput : AVCapturePhotoOutput!
var previewLayer : AVCaptureVideoPreviewLayer!
var device:AVCaptureDevice!
var currentViewControl = UIViewController()
var tempImageHolder = UIImage()

func beginCamera(_ targetView: UIView, _ currentVC: UIViewController) 
{ 
    currentViewControl = currentVC
    // Do any additional setup after loading the view, typically from a nib.
    captureSesssion = AVCaptureSession()
    captureSesssion.sessionPreset = AVCaptureSession.Preset.photo
    cameraOutput = AVCapturePhotoOutput()

    if #available(iOS 11.1, *) {
        let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera, .builtInTelephotoCamera, .builtInTrueDepthCamera], mediaType: AVMediaType.video, position: .back).devices
        device = availableDevices.first
    } else {
        // Fallback on earlier versions
        device = AVCaptureDevice.default(for: .video)!
    }

    if let input = try? AVCaptureDeviceInput(device: device!) {
        if (captureSesssion.canAddInput(input)) {
            captureSesssion.addInput(input)
            if (captureSesssion.canAddOutput(cameraOutput)) {
                captureSesssion.addOutput(cameraOutput)
                let connection = cameraOutput.connection(with: AVFoundation.AVMediaType.video)
                connection?.videoOrientation = .portrait
                previewLayer = AVCaptureVideoPreviewLayer(session: captureSesssion)
                self.previewLayer.frame = targetView.frame
                self.previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
                //setOutputOrientation()
                targetView.layer.addSublayer(previewLayer)
                captureSesssion.startRunning()
            }
        } else {
            print("issue here : captureSesssion.canAddInput")
        }
    } else {
        print("some problem here")
    }
    previewLayer?.frame.size = targetView.frame.size
}

   func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
    if let error = error {
        // we got back an error!
        let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        currentViewControl.present(alert, animated: true)
    } else {
    }}


 func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    let imageData = photo.fileDataRepresentation()
    let imageSize: Int = imageData!.count
    print(imageSize)
    tempImageHolder = UIImage(data: (imageData! as NSData) as Data)!
    //When use this below line works fine when take images from left landscape, but when take images from right landscape image not show properly screen shot below:
    tempImageHolder = UIImage(cgImage: tempImageHolder.cgImage!, scale: tempImageHolder.scale, orientation: .up)
    }
}

Lorsque vous utilisez cette ligne ci-dessus fonctionne correctement lorsque vous prenez des images à partir d'un paysage de gauche, mais lorsque vous prenez des images à partir d'une image de paysage de droite, la capture d'écran ne s'affiche pas correctement

Peut quelqu'un s'il vous plaît m'expliquer comment faire pivoter l'image. Toute aide serait grandement appréciée.

Merci d'avance.


3 commentaires

Pouvez-vous publier le code que vous utilisez pour afficher l'image? Il est préférable de savoir quel type de hiérarchie de vues vous utilisez ici.


D'accord....


@ ev350 veuillez vérifier


5 Réponses :


0
votes
var tempImage = imgae
        guard let cgImage = imgae?.cgImage else {return}

        if let orientedImage = cgImage.orientImage(.upMirrored) {
            tempImage = UIImage(cgImage: orientedImage)
        }
        let image = UIImageView(image: tempImage)

2 commentaires

Merci pour votre réponse, mais le même problème se produit lors de l'utilisation de votre solution et veuillez consulter mes questions mises à jour pour plus d'informations


Avez-vous essayé avec ci-dessus lorsque vous définissez une image dans Imageview? Cela devrait être imageView.image = capturéImage.fixOrientation ()



0
votes

Le problème est que vous supprimez les métadonnées de votre image (y compris l'orientation) lors de la conversion de votre UIImage en CGImage . Vous devez afficher une nouvelle UIImage avant d'accéder à sa propriété cgImage comme je l'ai montré dans ce post


if let data = photo.fileDataRepresentation(), let image = UIImage(data: data) {
    let renderedImage = UIGraphicsImageRenderer(size: size, format: imageRendererFormat).image { _ in image.draw(at: .zero) }
    // use renderedImage image
}


2 commentaires

qu'est-ce que imageRendererFormat ?


developer.apple.com/documentation/uikit/…



0
votes

Essayez la fonction suivante pour corriger l'orientation:

extension UIImage {
    func makeFixOrientation() -> UIImage {
        if self.imageOrientation == UIImage.Orientation.up {
            return self
        }

        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        return normalizedImage;
    }
}


0 commentaires

2
votes

C'est un problème vraiment ennuyeux, et je ne peux vraiment pas croire qu'AVFoundation n'ait rien de plus facile pour nous. Mais dans mes applications, je le fais en tenant autour de l'orientation actuelle de l'appareil. Lorsque la sortie photo revient avec une image, faites pivoter l'image en utilisant l'orientation pour vous assurer que tout est représenté vers le haut.

class MyViewController: UIViewController {

    var currentOrientation: UIDeviceOrientation = .portrait

    override func viewDidLoad() {
        NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: UIDevice.orientationDidChangeNotification, object: nil)
    }

    @objc func orientationChanged() {
        currentOrientation = UIDevice.current.orientation
    }

    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        guard let img = photo.cgImageRepresentation()?.takeUnretainedValue() else { return }
        let temp = CIImage(cgImage: img)
        var ciImage = temp;
        switch currentOrientation {
            case .portrait:
                ciImage = temp.oriented(forExifOrientation: 6)
            case .landscapeRight:
                ciImage = temp.oriented(forExifOrientation: 3)
            case .landscapeLeft:
                ciImage = temp.oriented(forExifOrientation: 1)
            default:
                break
        }

        guard let cgImage = CIContext(options: nil).createCGImage(ciImage, from: ciImage.extent) else { return }
        let fixedImage = UIImage(cgImage: cgImage)
    }


}

En fin de compte, utilisez fixedImage pour vos besoins. Veuillez noter que je m'abonne au centre de notification pour les changements d'orientation.


0 commentaires

0
votes

À partir d'iOS 4.0, lorsque l'appareil photo prend une photo, il ne tourne pas avant de l’enregistrer,

  • définit simplement un indicateur de rotation dans les données EXIF ​​du JPEG.Si vous enregistrez une UIImage au format JPEG
  • il définira l'indicateur de rotation. Les PNG ne prennent pas en charge un indicateur de rotation.
  • donc si vous enregistrez une UIImage au format PNG, elle sera tournée de manière incorrecte et aucun indicateur n'est défini pour le corriger. Donc, si vous voulez des images PNG, vous devez faites-les pivoter vous-même.
func rotateImage(image: UIImage) -> UIImage? {
            if (image.imageOrientation == UIImage.Orientation.up ) {
                return image
            }
            UIGraphicsBeginImageContext(image.size)
            image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
            let copy = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return copy
        }

0 commentaires