功能并不难,之所以被难住是因为把问题想复杂了,记录一下。

自定义的相机拍照使用AVCaptureSession,获取指定区域图片使用图片裁切功能,重点在于不能直接使用AVCaptureSession获取到的图片,需要对图片进行放大处理然后再裁切。

自定义相机

@property (nonatomic, strong) AVCaptureSession *captureSession; // 会话
@property (nonatomic, strong) AVCaptureDevice * captureDevice;   // 输入设备
@property (nonatomic, strong) AVCaptureDeviceInput * captureDeviceInput; // 输入源
@property (nonatomic, strong) AVCapturePhotoOutput *photoOutput;    // 图像输出
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; // 预览画面
@property (nonatomic, strong) AVCapturePhotoSettings *photoSettings;    // 图像设置
@property (nonatomic, assign) AVCaptureDevicePosition position;#pragma mark - 创建会话
-(AVCaptureSession *)captureSession{if (!_captureSession) {_captureSession = [[AVCaptureSession alloc] init];_captureSession.sessionPreset = AVCaptureSessionPresetPhoto; // 画质}return _captureSession;
}#pragma mark - 创建输入设备
-(AVCaptureDevice *)captureDevice{if (!_captureDevice) {//        设置默认前置摄像头_captureDevice = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionBack];}return _captureDevice;
}#pragma mark - 创建输入源
-(AVCaptureDeviceInput *)captureDeviceInput{if (!_captureDeviceInput) {_captureDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:nil];}return _captureDeviceInput;
}#pragma mark - 创建图像输出
-(AVCapturePhotoOutput *)photoOutput{if (!_photoOutput) {_photoOutput = [[AVCapturePhotoOutput alloc] init];}return _photoOutput;
}-(AVCaptureVideoPreviewLayer *)previewLayer{if (!_previewLayer) {_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;}return _previewLayer;
}- (instancetype)initWithFrame:(CGRect)frame
{self = [super initWithFrame:frame];if (self) {[self.layer insertSublayer:self.previewLayer atIndex:0];// 5. 连接输入与会话if ([self.captureSession canAddInput:self.captureDeviceInput]) {[self.captureSession addInput:self.captureDeviceInput];}// 6. 连接输出与会话if ([self.captureSession canAddOutput:self.photoOutput]) {[self.captureSession addOutput:self.photoOutput];}[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationWillEnterForegroundNotification object:nil];}return self;
}#pragma mark - 开始运行
-(void)startRunning {dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{[self.captureSession startRunning];});
}#pragma mark - 停止运行
-(void)stopRunning{dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{[self.captureSession stopRunning];});
}#pragma mark - 拍照
-(void)shutterCamera {self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:@{AVVideoCodecKey:AVVideoCodecTypeJPEG}];[self.photoSettings setFlashMode:self.mode];if (!self.previewLayer || !self.photoOutput || !self.photoSettings) {return;}if (self.captureSession.isRunning == YES) {[self.photoOutput capturePhotoWithSettings:self.photoSettings delegate:self];}
}

加上相框和按钮的效果:

拍照回调代理方法获取图片:

#pragma mark - 拍照回调代理
- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(NSError *)error{if (!error) {NSData *imageData = [photo fileDataRepresentation];UIImage *image = [UIImage imageWithData:imageData];//保存原始图片UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);CGFloat width = self.previewLayer.frame.size.width;CGFloat height = self.previewLayer.frame.size.height;CGSize size = CGSizeMake(width, height);//使用的SDWebImage提供的图片缩放处理方法UIImage *scaledImage = [image sd_resizedImageWithSize:size scaleMode:(SDImageScaleModeAspectFill)];//保存放大后的图片UIImageWriteToSavedPhotosAlbum(scaledImage, nil, nil, nil);//使用的SDWebImage提供的图片裁切处理方法UIImage *targetImage = [scaledImage sd_croppedImageWithRect:CGRectMake(self.clipArea.origin.x, self.clipArea.origin.y, self.clipArea.size.width, self.clipArea.size.height)];//图片翻转UIImage *newImage = [UIImage imageWithCGImage:targetImage.CGImage scale:1.0f orientation:(UIImageOrientationLeft)];//保存裁切后图片UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil);if (image) {[self saveImageWithImage:newImage];}}
}

需要注意的是,获取到的原始图片内容尺寸要比拍照屏幕尺寸大而且是按照宽度自适应的,而我们需要的虚线框中的内容是从全屏宽高的图片中裁切出来的:

左边是获取到的原始图片,右边是我们通过摄像头看到的内容,右边是左边图片等比放大到高度与屏幕高度一样的效果,所以要对原始图片进行放大处理,然后再根据虚线框的位置frame裁切要想的内容。

至于为什么AVCaptureSession获取到的全屏图片内容要比我们看到的内容要多,还得继续查找原因。

iOS-自定义相机拍照获取指定区域图片相关推荐

  1. iOS开发- 相机(摄像头)获取到的图片自动旋转90度解决办法

    http://www.tuicool.com/articles/IfEZre 今天写demo的时候发现, 如果把通过相机获取到的图片,直接进行操作, 比如裁剪, 缩放, 则会把原图片向又旋转90度. ...

  2. 微信小程序拍照截取指定区域图片(话不多说,直接上代码)

    效果图 wxml <camera wx:if='{{isShowCamera}}' class="camera-box" devic-position="width ...

  3. Unity for IOS 加载手机相册图片以及打开相机拍照获取图片

    Unity for IOS 加载手机相册图片以及打开相机拍照获取图片 最近想做一个使用unity for IOS获取手机图片的功能,所以就研究了一下 这里我们需要创建两个objective-c文件,最 ...

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

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

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

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

  6. 微信小程序:拍照画布指定区域生成图片

    最近写识别行驶证功能,点击拍照把指定区域截取,生成图片功能. 系统相机.该组件是原生组件,使用时请注意相关限制. 扫码二维码功能,需升级微信客户端至6.7.3. 微信小程序Camera相机地址 我们看 ...

  7. android自定义相机拍照

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

  8. android 调用系统相机拍照 获取原图

    博客源址:android 调用系统相机拍照 获取原图 博客时间:2013-04-23 11:08 好吧,为了这个问题又折腾了一整天.之前在网上找来的方法,如果在onActivityResult中直接用 ...

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

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

最新文章

  1. JavaScript教程之DOM和BOM
  2. 人生第一次删好友,删的就是你!连路飞都怒了!
  3. target evaluations
  4. 数据可视化(BI报表的开发)第二天
  5. 预售┃每个人都应该学习编程,因为它会教你如何思考
  6. leetcode 338. 比特位计数
  7. Python自带又好用的代码调试工具Pdb学习笔记
  8. 页面间参数传递---基于Vue的uniapp手机端_前端UI_uview工作笔记005
  9. 2021.01.04
  10. 无盘工作站建立全攻略
  11. kb4023057安装失败_微软向旧版Windows 10推送易升补丁出现无法安装问题
  12. 【NanoPi T2】 8.uboot gmac网卡驱动(4) - 移植rtl8211e网卡驱动(首发)
  13. 修复黑客利用Freemius类绕过过身份验证的选项(漏洞-wordpress)
  14. win7计算机启动遇到错误怎么办,W7电脑系统出现Windows错误恢复该怎么办
  15. 【地理中国】百年地理大发现(全8集)内容笔记记录
  16. 辨别身份真假之【天眼数聚】腾讯云身份证实名认证接口
  17. 计算机里FC方式,谁知道头文字D里提到的FD,FR,FC,FF指的是什么驱动方式的车?...
  18. Firefox(火狐浏览器)常用插件
  19. 四川嘉庆恒运:拼多多上买化妆品靠谱不
  20. 安卓手机如何快速投屏到windows(10/8.1/7)电脑上

热门文章

  1. centos java 时间差8个小时_解决Centos7本机时间与实际时间相差8小时
  2. Win 7 Tornado 2.2 安装指南
  3. 【ios6降级教程】A4设备ios6降级到ios5.1.1(sn0wbreeze+shsh)
  4. JavaScript 王者归来
  5. logback报错:ERROR in ch.qos.logback.core.joran.conditional.IfAction
  6. ehcache 冲突_ehcache版本冲突
  7. 华为测试c语言面试题,硬件测试笔试题
  8. lync2010企业版部署
  9. java svg 转pdf_Java PDF转HTML、Word、图片、SVG、XPS、 PDF/A等格式
  10. (附源码)计算机毕业设计ssm互联网在线笔记管理系统