照片旋转是个头疼的问题,找了很多网上的资料,显示最多的就是这个:
-(UIImage *)fixFixOrientation;
但是用起来是有问题的,你会发现前置摄像头不能纠正倒影成像,拍照界面不能强制竖屏,横屏拍照无法在竖屏下旋转至正确的用户使用方向...;
前人栽树,抛砖引玉,给大家推荐下我自己的纠偏方案[代码量其实可以缩进]:
我用的是AVCaptureSession,自定义的一个controller作为容器;
一.跳转前的配置:
1. 临时存储一下设备方向:
NSInteger beforeOrientation = [UIDevice currentDevice].orientation;
2.跳转前强制竖屏:
[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
3.present回调中修正device正确方向:
[self presentViewController:contr animated:YES completion:^{
[[UIDevice currentDevice]setValue:@(beforeOrientation)forKey:@"orientation"];
}];
说明:这个坑的填法解决了以下几个问题:
1解决横竖屏适配的问题,只要竖屏,真爽;
2.解决跳转前横屏下检测不到device正确方向的问题,如果不这样设置,横屏跳转后用户如果交互没有唤醒device旋转监听,image纠偏就需要做更多的处理;
二.拍照回调中:
- (void)captureOutput:(AVCapturePhotoOutput*)output didFinishProcessingPhoto:(nonnull AVCapturePhoto*)photo error:(nullable NSError*)error {
if(!error) {
// NSLog(@"照片拍摄完成");
NSData*imageData = [photo fileDataRepresentation];
UIImage*image = [UIImage imageWithData:imageData];
// 当前输入设备是前置摄像头
if (_currentCameraInput == _frontdeviceInput) {
// 前置摄像头倒影成像纠偏
image = [[UIImage alloc]initWithCGImage:image.CGImage scale:1.0f orientation:UIImageOrientationLeftMirrored];
// 网上流行的fixOrientation升级版
image = [image fixOrientationByCameraLocation:YES];
}else{
image = [image fixOrientationByCameraLocation:NO];
}
// 处理横屏拍照后,使得image在竖屏下展示正确的用户使用方向
// device头朝左
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft) {
// 横屏拍照旋转
image = [image landscapefixOrientation:NO];
}
// device头朝右
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
image = [image landscapefixOrientation:YES];
}
NSData *da = UIImagePNGRepresentation(image);
// 处理data
[selfhandleShotDone:da];
}
}
三.然后是写在延展下的调用方法,这块是借鉴网友后自己修改的:
- (UIImage*)fixOrientationByCameraLocation:(BOOL)isFront {
NSLog(@"-------%ld",(long)self.imageOrientation);
// No-op if the orientation is already correct
CGAffineTransform transform = CGAffineTransformIdentity;
if (self.imageOrientation == UIImageOrientationUp) return self;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
switch (self.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform =CGAffineTransformTranslate(transform, self.size.width, self.size.height);
transform =CGAffineTransformRotate(transform,M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform =CGAffineTransformTranslate(transform,self.size.width,0);
transform =CGAffineTransformRotate(transform,M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform =CGAffineTransformTranslate(transform,0,self.size.height);
transform =CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (self.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform =CGAffineTransformTranslate(transform,self.size.width,0);
transform =CGAffineTransformScale(transform, -1,1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform =CGAffineTransformTranslate(transform,self.size.height,0);
transform =CGAffineTransformScale(transform, -1,1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage),0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
returnimg;
}
- (UIImage*)landscapefixOrientation:(BOOL)isleft {
CGAffineTransform transform = CGAffineTransformIdentity;
// No-op if the orientation is already correct
if (self.imageOrientation == UIImageOrientationUp) {
if(isleft ==YES) {
NSLog(@"HOME键在左侧");
transform =CGAffineTransformTranslate(transform,0,self.size.width);
transform =CGAffineTransformRotate(transform, -M_PI_2);
}else{
NSLog(@"HOME键在右侧");
transform =CGAffineTransformTranslate(transform,self.size.height,0);
transform =CGAffineTransformRotate(transform,M_PI_2);
}
}else{
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL,
self.size.height,
self.size.width,
CGImageGetBitsPerComponent(self.CGImage),
0,
CGImageGetColorSpace(self.CGImage), //CGImageGetColorSpace(self.CGImage)
CGImageGetBitmapInfo(self.CGImage)//CGImageGetBitmapInfo(self.CGImage)
);
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
returnimg;
}
另外就是几个基本的配置:
#pragma mark - 隐藏电池条
- (BOOL)prefersStatusBarHidden {
return YES;
}
#pragma mark - 强制竖屏
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate{
return NO;
}
我自己录了个屏供大家看下效果:
https://s31.aconvert.com/convert/p3r68-cdx67/eck4f-p9z4l.gif