[ios开发]锁屏后的相机的方向检查,与图片的自动旋转

关键词:imageOrientation, 自动旋转, 获取方向, 锁屏, 图片方向, 自定义拍照
问题描述:


一个同事开发iphone拍照后为图片添加滤镜的功能。 发现添加滤镜时总出现方向自动变化的问题。 


分析原因:

1 方向没有搞正确。 

2 给滤镜方法时图片没有正过来。 


1 方向没有搞正确。

解决方法:

因为UIImage本身就自带的imageOrientation的 值, 一般情况下调用相机拍照会自动为照片添加imageOrientation. 但我们使用的是自定义相机功能,所以在拍照时需要为先设定方向值。 而获取方向使用到了通知, 在锁屏的情况下, 方向通知就无法获取了。见如下代码。  google无数页面后, 可以在锁屏方式仍可获取方向的方法。 见如下:


// 通过通知获取方向:(在锁屏方式下无法获取方向) 


[notificationCenter addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];


- (void)deviceOrientationDidChange

{

UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];

    

if (deviceOrientation == UIDeviceOrientationPortrait)

orientation = AVCaptureVideoOrientationPortrait;

elseif (deviceOrientation == UIDeviceOrientationPortraitUpsideDown)

orientation = AVCaptureVideoOrientationPortraitUpsideDown;

// AVCapture and UIDevice have opposite meanings for landscape left and right (AVCapture orientation is the same as UIInterfaceOrientation)

elseif (deviceOrientation == UIDeviceOrientationLandscapeLeft)

orientation = AVCaptureVideoOrientationLandscapeRight;

elseif (deviceOrientation == UIDeviceOrientationLandscapeRight)

orientation = AVCaptureVideoOrientationLandscapeLeft;

// Ignore device orientations for which there is no corresponding still image orientation (e.g. UIDeviceOrientationFaceUp)

}



// 通过加速器获取方向

参考了老外的博客: http://blog.sallarp.com/iphone-accelerometer-device-orientation/


1

[[UIAccelerometersharedAccelerometer] setDelegate:self];


2

@interface AVCamCaptureManager : NSObject<UIAccelerometerDelegate>{

    UIInterfaceOrientation deviceOrientation;

}


@property (nonatomic) UIInterfaceOrientation deviceOrientation;


3


#pragma mark -- 方向


- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration

{

// Get the current device angle

float xx = -[acceleration x];

float yy = [acceleration y];

float angle = atan2(yy, xx);

// Read my blog for more details on the angles. It should be obvious that you

// could fire a custom shouldAutorotateToInterfaceOrientation-event here.

if(angle >= -2.25 && angle <= -0.25)

{

if(deviceOrientation != UIInterfaceOrientationPortrait)

{

deviceOrientation = UIInterfaceOrientationPortrait;

}

}

else if(angle >= -1.75 && angle <= 0.75)

{

if(deviceOrientation != UIInterfaceOrientationLandscapeRight)

{

deviceOrientation = UIInterfaceOrientationLandscapeRight;

}

}

else if(angle >= 0.75 && angle <= 2.25)

{

if(deviceOrientation != UIInterfaceOrientationPortraitUpsideDown)

{

deviceOrientation = UIInterfaceOrientationPortraitUpsideDown

}

}

else if(angle <= -2.25 || angle >= 2.25)

{

if(deviceOrientation != UIInterfaceOrientationLandscapeLeft)

{

deviceOrientation = UIInterfaceOrientationLandscapeLeft

}

}

    orientation = deviceOrientation

    

}


// 自定义拍照方式设置方向:


[stillImageConnection setVideoOrientation:deviceOrientation];


代码如下: 

- (void) captureStillImage

{

    AVCaptureConnection *stillImageConnection = [AVCamUtilitiesconnectionWithMediaType:AVMediaTypeVideofromConnections:[[selfstillImageOutput] connections]];

 

    if ([stillImageConnection isVideoOrientationSupported])

    {

        NSLog(@"device orientation: %d", deviceOrientation);

        [stillImageConnection setVideoOrientation:deviceOrientation];

    }



2 给滤镜方法时图片没有正过来。 

生成后的图片会自带一个imageOrientation的值, 默认情况下UIImageView会自动判断这个值之后做旋转显示, 但我们自己如果要画到页面上时就需要对图片做相就的旋转: 

google到的: 

http://stackoverflow.com/questions/5427656/ios-uiimagepickercontroller-result-image-orientation-after-upload/5427890#5427890


// 自动旋转图片


- (UIImage* )rotateImage:(UIImage *)image {

    int kMaxResolution = 320;

    // Or whatever

    CGImageRef imgRef = image.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);

    CGFloat height = CGImageGetHeight(imgRef);

    CGAffineTransform transform = CGAffineTransformIdentity;

    CGRect bounds = CGRectMake(0, 0, width, height);

    if (width > kMaxResolution || height > kMaxResolution) {

        CGFloat ratio = width  /  height;

        if (ratio > 1 ) {

            bounds.size.width = kMaxResolution;

            bounds.size.height = bounds.size.width / ratio;

        }

        else {

            bounds.size.height = kMaxResolution;

            bounds.size.width = bounds.size.height * ratio;

        }

    }

    CGFloat scaleRatio = bounds.size.width / width;

    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));

    CGFloat boundHeight;

    UIImageOrientation orient = image.imageOrientation;

    switch (orient) {

        caseUIImageOrientationUp:

            //EXIF = 1

            transform = CGAffineTransformIdentity;

            break;

        caseUIImageOrientationUpMirrored:

            //EXIF = 2

            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);

            transform = CGAffineTransformScale(transform, -1.0, 1.0 );

            break;

        caseUIImageOrientationDown:

            //EXIF = 3

            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);

            transform = CGAffineTransformRotate(transform, M_PI);

            break;

        caseUIImageOrientationDownMirrored:

            //EXIF = 4

            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);

            transform = CGAffineTransformScale(transform, 1.0, -1.0);

            break;

        caseUIImageOrientationLeftMirrored:

            //EXIF = 5

            boundHeight = bounds.size.height;

            bounds.size.height = bounds.size.width;

            bounds.size.width = boundHeight;

            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width );

            transform = CGAffineTransformScale(transform, -1.0, 1.0);

            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0 );

            break;

        caseUIImageOrientationLeft:

            //EXIF = 6

            boundHeight = bounds.size.height;

            bounds.size.height = bounds.size.width;

            bounds.size.width = boundHeight;

            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);

            transform = CGAffineTransformRotate( transform, 3.0 * M_PI / 2.0  );

            break;

        caseUIImageOrientationRightMirrored:

            //EXIF = 7

            boundHeight = bounds.size.height;

            bounds.size.height = bounds.size.width;

            bounds.size.width = boundHeight;

            transform = CGAffineTransformMakeScale(-1.0, 1.0);

            transform = CGAffineTransformRotate( transform, M_PI / 2.0);

            break;

        caseUIImageOrientationRight:

            //EXIF = 8

            boundHeight = bounds.size.height;

            bounds.size.height = bounds.size.width;

            bounds.size.width = boundHeight;

            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);

            transform = CGAffineTransformRotate(transform, M_PI / 2.0 );

            break;

        default:

            [NSExceptionraise:NSInternalInconsistencyExceptionformat:@"Invalid image orientation"];

    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {

        CGContextScaleCTM(context, -scaleRatio, scaleRatio);

        CGContextTranslateCTM(context, -height, 0);

    }

    else {

        CGContextScaleCTM(context, scaleRatio, -scaleRatio);

        CGContextTranslateCTM(context, 0, -height);

    }

    CGContextConcatCTM(context, transform );

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);

    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return imageCopy;

}





    

就算当不成英雄,也要是一条好汉| 空谈误国,实干兴邦。
原文地址:https://www.cnblogs.com/liangzhimy/p/2789224.html