1 , 自定义相机,拿到照片,校正方向
AVCapturePhotoCaptureDelegate 的这个代理方法
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?)
拿照片,
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()
}
}
}
拿到照片后,让照片的头部朝上
extension UIImage {
// 修复转向
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)
}
}
照片朝上,不用管,
朝左、朝右、朝下,都有一个旋转,
旋转后,相应的翻转坐标系,
然后从绘图上下文中,取出照片
2 , 旋转照片
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)
}
弄一个属性,记录已经旋转了多少个 90 度,
旋转图片视图 takedImageView,
限定图片视图的 frame,
图片视图的 frame, 要么跟屏幕一致,要么根据分辨率
根据分辨率:
- 此时, image.height > image.width
视图的 width = 屏幕 width,
然后等图片比例放大,可接受
就算 image.height > 屏幕 height,
也 OK
- 此时, image.height <= image.width
视图的 width = 屏幕 width,
等图片比例放大,可接受
然后指定中心点
3, 重拍
@objc
func retakeBtnClick(){
angleX = 0
takedImageView.transform = .identity
takedImageView.frame = view.bounds
session.startRunning()
resetSubViewStatus()
takedImage = nil
}
恢复,记录的旋转角度
takedImageView 的 frame 和 transform 都重置
4, 结束旋转
@objc func doneBtnClick() {
recordVideoPlayerLayer?.player?.pause()
recordVideoPlayerLayer?.player = nil
dismiss(animated: true) {
self.takeDoneBlock?(self.takedImage?.image(rotated: Int(self.angleX)))
}
}
根据旋转的角度,拿原图绘制,新图
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.x, y: 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
}
}