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.
5 Réponses :
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)
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 ()
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 }
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; } }
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.
À 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 }
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