一个同事开发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到的:
// 自动旋转图片
- (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;
}