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.takedImageself.takedImageView.isHidden = falseself.resetSubViewStatus()}}}

拿到照片后,让照片的头部朝上

extension UIImage {// 修复转向func fixOrientation() -> UIImage {if self.imageOrientation == .up {return self}var transform = CGAffineTransform.identityswitch 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 = 0func rotateRhs() {guard let img = takedImage else {return}let radian = CGFloat.pi * 0.5angleX += 1takedImageView.transform = CGAffineTransform(rotationAngle: radian * angleX)if Int(angleX) % 2 == 1{takedImageView.frame = view.bounds}else{let ratio = img.size.height / img.size.widthlet w = UI.std.widthlet h = w * ratiotakedImageView.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, 重拍

    @objcfunc retakeBtnClick(){angleX = 0takedImageView.transform = .identitytakedImageView.frame = view.boundssession.startRunning()resetSubViewStatus()takedImage = nil}

恢复,记录的旋转角度

takedImageView 的 frame 和 transform 都重置

4, 结束旋转

@objc func doneBtnClick() {recordVideoPlayerLayer?.player?.pause()recordVideoPlayerLayer?.player = nildismiss(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 / 2let rotatedSize = CGRect(origin: .zero, size: size).applying(CGAffineTransform(rotationAngle: radian)).integral.sizeUIGraphicsBeginImageContext(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}}

github 链接

iOS 自定义相机,拍照旋转相关推荐

  1. uni-app 自定义相机拍照录像,可设置分辨率、支持横竖屏(ios、android)

    插件市场:uni-app 自定义相机拍照录像,可设置分辨率.支持横竖屏(ios.android)

  2. android自定义相机拍照

     Android中开发相机的两种方式: Android系统提供了两种使用手机相机资源实现拍摄功能的方法,一种是直接通过Intent调用系统相机组件,这种方法快速方便,适用于直接获得照片的场景,如上传相 ...

  3. Android自定义相机拍照、图片裁剪的实现

    原文:Android自定义相机拍照.图片裁剪的实现 最近项目里面又要加一个拍照搜题的功能,也就是用户对着不会做的题目拍一张照片,将照片的文字使用ocr识别出来,再调用题库搜索接口搜索出来展示给用户,类 ...

  4. android 自定义拍照模糊,Android自定义相机拍照模糊处理

    问题分析:随着用户对于拍照清晰度的需求,android手机对于摄像头也是一升再升,这就导致了作为android开发工程师对于兼容性维护的继续跟进以及问题处理. 针对于自定义相机拍照模糊的问题,经过几天 ...

  5. 微信小程序自定义相机拍照,计算大小,以及上传

    需求:近来微信小程序有个需求,自定义相机拍照,并且要在相机中画一个框,提示用户把拍摄内容放入框中,类似于上传身份证时那个头像,国徽对其的框.(因为我们上传的是一份A4纸的病例),所以需要这样.然后后台 ...

  6. ios 自定义拍照页面_iOS开发笔记:自定义相机拍照

    目录 之前用AVFoundation自定义相机做了拍照与视频相关的东西,为什么要自定义呢?主要是提供更个性化的交互设计,符合app主题,对于视频来说,也便于提供更多丰富有趣的功能.前段时间整理了下拍照 ...

  7. iOS自定义相机实现拍照和连拍

    我们常用的拍照模块,大部分代码都是一样的,甚至都不用改就可以直接拖进项目里面使用.但是这仅仅是简单的相机拍照功能,如果我们希望使用更多的功能,比如说连拍等,就需要多一点处理. 我们还是使用UIImag ...

  8. ios 自定义拍照页面_iOS 自定义相机拍照,手动对焦和自动对焦

    天下虚怀接空谷,何处高峰不入云. 一.相机界面绘制需要的一些宏 #define kScreenBounds [UIScreen mainScreen].bounds #define kPhotogra ...

  9. IOS 自定义相机, 使用 AVFoundation(附实现部分腾讯水印相机功能 demo)

    原文链接:http://www.jianshu.com/p/c64bf543f16a 这是一款使用 AVFoundation 自定义的相机,与系统原生相机有一样的外观但比系统的相机更好.更符合实际的开 ...

最新文章

  1. lay弹窗库的一个坑
  2. 2019年平面设计趋势
  3. Struts.xml配置解释
  4. android 揭示动画_遗传编程揭示具有相互作用的多元线性回归
  5. 计算机英语讲课笔记(2020-6-13)
  6. 【nginx】nginx 高可用集群
  7. 微云笔记控制脚本实例:远程控制脚本开关
  8. DLNA和UPnP是什么关系?通俗解释
  9. bzoj 4815: [Cqoi2017]小Q的表格
  10. coffe-script
  11. Vue-amap 实现获取定位功能
  12. 前端项目使用阿里巴巴icon font的具体过程
  13. yaourt下载速度太慢_加快Yaourt软件包的安装速度
  14. 电脑上的文件如何备份到服务器,怎么将电脑备份到云服务器
  15. Qt中pri文件介绍及使用(图文超级简单!!)
  16. openssl RSA、AES、DES、MD5、SHA1,CA
  17. 说实话,Windows8还是可圈可点的
  18. 成人赛道IT职业教育将迎来“黄金发展期”
  19. 程序员工作四五年后,就算大龄了吗?
  20. 一、任务调度中心构建示例

热门文章

  1. RPA:让电商财务拥有“分身术”
  2. 个人总结:Mysql知识图谱
  3. urllib库的学习与使用
  4. 0xc0000005 系统应用日志_0xc0000005,小编教你怎么解决应用程序正常初始化0xc0000005失败...
  5. Feign传输MultipartFile 报错 Error converting request body
  6. 计算机中现代操作系统两个基本特征是什么,现代操作系统的两个基本特征是资源共享和...
  7. 计算机进安全模式启动修复,win7电脑故障怎么进入安全模式修复
  8. 论文研读-社交媒体可视化-地图隐喻转发地图R-Map
  9. .csd文件怎么读?--CMU_MOSI_Opinion_Labels.csd
  10. iOS实现App之间的分享