1. Customize the camera, get the photo, and correct the direction

AVCapturePhotoCaptureDelegate method of the agent

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) 
Copy the code

Take photos,

extension ZLCustomCamera: AVCapturePhotoCaptureDelegate { public func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { if error ! = nil { return } if let imgData = photo.fileDataRepresentation(){ self.session.stopRunning() if let img = UIImage(data: imgData){ self.takedImage = img.fixOrientation() } self.takedImageView.image = self.takedImage self.takedImageView.isHidden = false self.resetSubViewStatus() } } }Copy the code

When you get the photo, turn it upside down

Func fixOrientation() -> UIImage {if self.imageorientation ==.up {return self} var transform = CGAffineTransform.identity switch self.imageOrientation { case .down, .downMirrored: transform = CGAffineTransform(translationX: self.size.width, y: self.size.height) transform = transform.rotated(by: .pi) case .left, .leftMirrored: transform = CGAffineTransform(translationX: self.size.width, y: 0) transform = transform.rotated(by: CGFloat.pi / 2) case .right, .rightMirrored: transform = CGAffineTransform(translationX: 0, y: self.size.height) transform = transform.rotated(by: -CGFloat.pi / 2) default: break } switch self.imageOrientation { case .upMirrored, .downMirrored: transform = transform.translatedBy(x: self.size.width, y: 0) transform = transform.scaledBy(x: -1, y: 1) case .leftMirrored, .rightMirrored: transform = transform.translatedBy(x: self.size.height, y: 0) transform = transform.scaledBy(x: -1, y: 1) default: break } guard let ci = self.cgImage, let colorSpace = ci.colorSpace else { return self } let context = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: ci.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: ci.bitmapInfo.rawValue) context? .concatenate(transform) switch self.imageOrientation { case .left, .leftMirrored, .right, .rightMirrored: context? .draw(ci, in: CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width)) default: context? .draw(ci, in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)) } guard let newCgimg = context? .makeImage() else { return self } return UIImage(cgImage: newCgimg) } }Copy the code

Photo up, don’t worry about it,

To the left, to the right, to the down, there’s a spin,

After rotation, the corresponding inverted coordinate system,

Then, from the drawing context, pull out the photo

2. Rotate the photo

var angleX: CGFloat = 0 func rotateRhs() {guard let img = takedImage else {return} let radian = CGFloat. PI * 0.5 angleX += 1 takedImageView.transform = CGAffineTransform(rotationAngle: radian * angleX) if Int(angleX) % 2 == 1{ takedImageView.frame = view.bounds } else{ let ratio = img.size.height / img.size.width let w = UI.std.width let h = w * ratio takedImageView.frame = CGRect(x: 0, y: 0, width: w, height: H)} takedimageView.center = CGPoint(x: ui.std. width * 0.5, y: ui.std.height * 0.5)}Copy the code
Get a property that records how many 90 degrees it’s been rotated,

Rotate image view takedImageView,

Define the frame of the image view,

The frame of the image view is either screen – consistent or based on resolution

According to the resolution:
  • Height > image.width

View width = screen width,

Then wait for the image to be enlarged to acceptable proportions

Even if image.height > screen height,

Also OK

  • At this point, image.height <= image.width

View width = screen width,

Such as the scale of the picture, acceptable

Then specify the center point

3, the remake

    @objc
    func retakeBtnClick(){
        angleX = 0
        
        takedImageView.transform = .identity
        takedImageView.frame = view.bounds
        
        
        session.startRunning()
        resetSubViewStatus()
        takedImage = nil
        
    }
Copy the code

Restore, record the rotation Angle

The frame and Transform of the takedImageView are reset

4, end the rotation

@objc func doneBtnClick() { recordVideoPlayerLayer? .player? .pause() recordVideoPlayerLayer? .player = nil dismiss(animated: true) { self.takeDoneBlock? (self.takedImage? .image(rotated: Int(self.angleX))) } }Copy the code

According to the rotation Angle, take the original drawing, new drawing

extension UIImage{ func image(rotated time: Int) -> UIImage{ guard time ! = 0 else { return self } let radian = CGFloat(time) * CGFloat.pi / 2 let rotatedSize = CGRect(origin: .zero, size: size) .applying(CGAffineTransform(rotationAngle: radian)) .integral.size UIGraphicsBeginImageContext(rotatedSize) if let context = UIGraphicsGetCurrentContext() { let Origin = CGPoint(x: rotatedSize. Width / 2.0, y: rotatedSize. Height / 2.0) context.translateby (x: origin. origin.y) context.rotate(by: radian) draw(in: CGRect(x: -origin.y, y: -origin.x, width: size.width, height: size.height)) let rotatedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return rotatedImage ?? self } return self } }Copy the code

Making a link_