最近自己的 WZYCamera 经过多次测试出现了一些问题。
总结以下两点:
01 在水平放置 iPhone 拍摄的时候不允许竖屏拍摄的 cover 一直闪烁,导致没有一个合适的 iPhone 摆放姿势。
02 拍照闪退
分析错误成因以及解决办法:
01 不停闪烁是由于我们 cover 显示出来的判断依据是 iPhone 的自身角度以及 iPhone 和水平面夹角,而这个夹角是根据 iPhone 自身的陀螺仪并且通过计算得到的角度。所以说这个角度不是 iPhone 自动返回的,而是经过处理的一个值,这样一来,多少会有些误差和计算错误。那么解决办法就是拿到最原始的数据进行一个判断。也就是用陀螺仪直接返回的 x、y、z 直接进行判断。
02 拍照闪退是需要我们在拍照时对错误的返回进行一个判定,错误的返回我们就不要了。或许是由于光线不好,或许是由于对焦没完全成功,可能会返回 error,或者抛出系统方法自定义的异常。我将崩溃异常进行的捕捉和提交,发现错误的成因于此:
这个异常出现的原因我总结有这么几种:
① 如果你连续拍摄太多(太快)的照片。
② 如果 jpegSampleBuffer 为 NULL 或不是 JPEG 格式,此方法将抛出 NSInvalidArgumentException。
显然上图中的异常是第二种中的 NULL 类型。
具体代码修改:
01 解决不停闪烁的 bug。
/** 开启陀螺仪 */
- (void)startGyroUpdate {
if ([self.motionManger isDeviceMotionAvailable]) { //陀螺仪可用
// __weak typeof(self) weakSelf = self;
[self.motionManger setDeviceMotionUpdateInterval:0.3];
if (![self.motionManger isDeviceMotionActive]) {
[self.motionManger startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
//1.Gravity 获取手机的重力值在各个方向上的分量,根据这个就可以获得手机的空间位置,倾斜角度等
double gravityX = motion.gravity.x;
double gravityY = motion.gravity.y;
double gravityZ = motion.gravity.z;
//2.获取手机的倾斜角度(zTheta是手机与水平面的夹角, xyTheta是手机绕自身旋转的角度):
// double zTheta = atan2 (gravityZ, sqrtf(gravityX * gravityX + gravityY * gravityY)) / M_PI * 180.0;
// double xyTheta = atan2 (gravityX, gravityY) / M_PI * 180.0;
// 用 y 值来决定横竖屏拍摄比角度决定横竖屏拍摄更加的精确
if (gravityY <= 0.25 && gravityY >= - 0.25) {
_alertLabel.hidden = YES;
_coverView.hidden = YES;
_btn_takePhoto.enabled = YES;
} else {
_alertLabel.hidden = NO;
_coverView.hidden = NO;
_btn_takePhoto.enabled = NO;
}
// NSLog(@"zTheta=%f xyTheta=%f", zTheta, xyTheta);
NSLog(@"x --- %.2f,y --- %.2f,z --- %.2f", gravityX, gravityY, gravityZ);
}];
}
} else {
NSLog(@"陀螺仪不可用!");
}
}
02 解决拍照崩溃
/** 拍照按钮方法 */
- (void)takePhoto {
AVCaptureConnection *stillImageConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
if (!stillImageConnection)
{
NSLog(@"拍照失败");
// [SVProgressHUD showErrorWithStatus:@"请重新进行拍摄!"];
return;
}
UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation];
AVCaptureVideoOrientation avcaptureOrientation = [self avOrientationForDeviceOrientation:curDeviceOrientation];
[stillImageConnection setVideoOrientation:avcaptureOrientation];
[stillImageConnection setVideoScaleAndCropFactor:1];
__weak typeof(self) weakSelf = self;
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:stillImageConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer == NULL) {
NSLog(@"拍照失败");
// [SVProgressHUD showErrorWithStatus:@"请重新进行拍摄!"];
return;
}
if (error) {
NSLog(@"拍照失败");
return;
}
NSData *jpegData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *tempImage = [UIImage imageWithData:jpegData scale:1.0];
UIImage *image = [UIImage imageWithCGImage:tempImage.CGImage scale:1.0 orientation:UIImageOrientationUp];
// 将拍照所得照片返回
if ([weakSelf.delegate respondsToSelector:@selector(cameraViewController:didFinishPickingImage:)]) {
[weakSelf.delegate cameraViewController:self didFinishPickingImage:image];
NSLog(@"拍照完成!");
[weakSelf dismissViewControllerAnimated:YES completion:nil];
}
}];
}
大家可以进一步下载 WZYCamera 源码及 demo 进行下载学习。