照片旋轉是個頭疼的問題,找了很多網(wǎng)上的資料,顯示最多的就是這個:
-(UIImage *)fixFixOrientation;
但是用起來是有問題的,你會發(fā)現(xiàn)前置攝像頭不能糾正倒影成像,拍照界面不能強制豎屏,橫屏拍照無法在豎屏下旋轉至正確的用戶使用方向...;
前人栽樹,拋磚引玉,給大家推薦下我自己的糾偏方案[代碼量其實可以縮進]:
我用的是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旋轉監(jiān)聽,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];
// 網(wǎng)上流行的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];
? ? }
}
三.然后是寫在延展下的調用方法,這塊是借鑒網(wǎng)友后自己修改的:
- (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