关键词: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/archive/2012/11/26/2789224.html

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

  1. 【系统】win10锁屏后,护眼绿自动恢复解决

    针对自己电脑(其他人的不晓得),win10锁屏后,重新登录,护眼绿会自动恢复成白色,查询资料需要修改注册表两个地方: 1.计算机\HKEY_CURRENT_USER\Control Panel\Col ...

  2. iOS 解决苹果手机锁屏后APP退出的问题及app状态

    进入后台程序退出是由iOS系统管理决定的,但APP退出在后台后,只有10秒的持续运行时间,然后暂停.但该APP还在内存中,当出现内存警告,也就是别的APP要运行,而此时内存又不足的情况下,系统会回收停 ...

  3. 华为锁屏久了就显示无法连接服务器,ios 锁屏后网络连接服务器

    ios 锁屏后网络连接服务器 内容精选 换一换 有以下几种现象:将制作好的SD卡插入开发者板并上电后,开发者板LED1与LED2灯状态信息异常.将制作好的SD卡插入开发者板,并通过USB方式连接Ubu ...

  4. bugku 管理员系统 后台代码_不会吧,这也行?iOS后台锁屏监听摇一摇

    [toc] 背景介绍 一般情况下,出于省电.权限.合理性等因素考虑,给人的感觉是很多奇怪的需求安卓可以实现,但是iOS就无法实现!今天要介绍的需求也有这种感觉,就是"当 APP 处于后台或锁 ...

  5. IOS开发环境更换后重新制作Provisioning Profile证书详解

    IOS开发环境更换后重新制作Provisioning Profile证书详解 新换了台Macbook,又折腾了一遍Provisioning Profile证书,苹果的证书繁锁复杂,每次制作都相当麻烦, ...

  6. 解决手机锁屏后无法获取传感器数据终极方案 以小米、华为手机为例

    android开发 传感器采集数据断断续续(锁屏后不能继续正常采集数据)以小米手机为例 有人说,不要锁屏,保持常亮,我个人认为这种方法不可取(触屏会带来误操作:在手机(小米和华为,其他手机没试)上不用 ...

  7. 2020-08-23 W7电脑锁屏后,能让电脑处于运行状态吗?

    W7电脑锁屏后,能让电脑处于运行状态吗? https://zhidao.baidu.com/question/509418733.html 如何设置电脑锁屏后自动黑屏,但永不休眠,不睡眠也不会断网. ...

  8. android app应用后台休眠,安卓手机锁屏后程序自动关闭,怎么设置手机app允许锁屏后台运行...

    原标题:安卓手机锁屏后程序自动关闭,怎么设置手机app允许锁屏后台运行 安卓手机锁屏后,很多程序就会自动关闭,实际上,这是安卓手机的一种保护机制.为了使系统能够流畅稳定的运行以及更加省电,它都会在手机 ...

  9. win10锁定计算机会断网吗,Win10专业版如何设置锁屏后不断网?超详细的图文教程...

    大家都知道win10专业版系统在进入锁屏之后会进入睡眠.也就是这时候网络就断了,很多软件的运行就会中断.那么Win10专业版如何设置锁屏后不断网?一起来看看吧! 方法一:设置锁屏之后不睡眠 大家可以使 ...

最新文章

  1. Java Web编程的主要组件技术——Hibernate入门
  2. 免费和开源世界里面有很多好的邮件服务器
  3. [转]“Ceph浅析”系列之(二)—Ceph的设计思想
  4. Some Essential JavaScript Questions And Answers(2)
  5. 对比 SQL Server 2005 和 Oracle
  6. 看完后,别再说自己不懂用户画像了
  7. 用VC实现GIS系统基本功能
  8. JS组件系列——又一款MVVM组件:Vue(一:30分钟搞定前端增删改查)
  9. 2019的第一工作日
  10. 电脑操作精典密笈60式
  11. 【MPI学习4】MPI并行程序设计模式:非阻塞通信MPI程序设计
  12. linux命令行中的大括号,linux命令行学习(19):花括号扩展(brace expansion)
  13. 联想智能云教室_被低估的联想能复制微软之路吗? | 公司观察
  14. 英语语音篇 - 音标体系
  15. 移动通信核心网技术总结(四)IMS的网络架构和功能
  16. Atitit 手机号码选号 规范 流程 attilax总结 v2 r99.docx
  17. ESP32 入门笔记05: BLE 蓝牙客户端和服务器 (ESP32 for Arduino IDE)
  18. 学习笔记:Java虚拟机——JVM内存结构、垃圾回收、类加载与字节码技术
  19. L1-039. 古风排版解决
  20. QQ号、微信号java正则表达式

热门文章

  1. Pandas如何检测None和Nan
  2. Hue由于主备NameNode切换引发的问题
  3. Bitmap如何高效加载图片
  4. 查看python安装位置和已安装库的相关操作
  5. zyplayer-doc 1.0.1 发布,你家所需的文档管理工具他都承包了!
  6. 查找某个数据,找到后把符合条件数据的一行复制到另外一个地方
  7. c++11 多线程编程(二)------ 线程类构造函数深入理解
  8. VM虚拟机里安装Centos
  9. redis技术分享ppt_一线互联网架构师技术分享:基于redis的分布式锁实现
  10. python 路径规划最短距离_路径规划(最短路径)算法C#实现