iOS_UIImage的方向(imageOrientation)
一.重现问题:
拍照获得的图片,由于尺寸不对,需要拆切.但是有的图片拆切出来,方向就乱了.查找了一些质量才知道.图片还有个方向属性! imageOrientation.
二.一个图片包含两个方面的信息:
1.数据本身: 每个像素的颜色值.
2.文件头: 图片的基本信息.比如:图片的宽高.图片的方向信息.
三: 为什么会有图片方向?
为了让照片可以真实的反应人们拍摄时看到的场景,现在很多相机中就加入了方向传感器,它能够记录下拍摄时相机的方向,并将这一信息保存在照片中。照片的存储方式还是没有任何改变,它仍然是以相机的坐标系来保存,只是当相机来浏览这些照片时,相机可以根据照片中的方向信息,结合此时相机的方向,对照片进行旋转,从而转到适合人们观看的角度。
四: 什么叫EXIF?
维基百科上对其的解释为:
可交换图像文件格式常被简称为Exif(Exchangeable image file format),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据… Exif可以附加于JPEG、TIFF、RIFF等文件之中.
什么叫Orientation?
在EXIF涵盖的各种信息之中,其中有一个叫做Orientation (rotation)的标签,用于记录图像的方向,这便是相机写入方向信息的最终位置。它总共定义了八个值:

注意:对于上面的八种方向中,加了*的并不常见,因为它们代表的是镜像方向,如果不做任何的处理,不管相机以任何角度拍摄,都无法出现镜像的情况。
这个表格代表什么意义?我们来看第一行,值为1时,右边两列的值分别为:Row #0 is Top,Column #0 is Left side,其实很好理解,它表示照片的第一行位于顶端,而第一列位于左侧,那么这张照片自然就是以正常角度拍摄的。
五: 什么时候会造成图片方向不对?
用相机拍摄出来的照片含有EXIF信息,UIImage的imageOrientation属性指的就是EXIF中的orientation信息。
如果我们忽略orientation信息,而直接对照片进行像素处理或者drawInRect等操作,得到的结果是翻转或者旋转90之后的样子。这是因为我们执行像素处理或者drawInRect等操作之后,imageOrientaion信息被删除了,imageOrientaion被重设为0,造成照片内容和imageOrientaion不匹配。
所以,在对照片进行处理之前,先将照片旋转到正确的方向,并且返回的imageOrientaion为0。
六: 解决办法:
下面这个方法就是一个UIImage category中的方法,用它可以达到以上目的。
方法一: 最直观的方法.
- (UIImage *)fixOrientation {
// No-op if the orientation is already correct
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.
CGAffineTransform transform = CGAffineTransformIdentity;
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, );
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, , 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, );
transform = CGAffineTransformScale(transform, -, );
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, );
transform = CGAffineTransformScale(transform, -, );
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), ,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(,,self.size.height,self.size.width), self.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(,,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);
return img;
}
方法二: 这里是利用了UIImage中的drawInRect方法,它会将图像绘制到画布上,并且已经考虑好了图像的方向.
- (UIImage *)normalizedImage {
if (self.imageOrientation == UIImageOrientationUp) return self;
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[self drawInRect:(CGRect){, , self.size}];
UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return normalizedImage;
}
技术支持: http://www.cocoachina.com/ios/20150605/12021.html
iOS_UIImage的方向(imageOrientation)的更多相关文章
- 别忽视UIImage中的方向属性, imageOrientation-转
转 : 别忽视UIImage中的方向属性, imageOrientation
- 关于imageOrientation
用相机拍出来的照片都含有EXIF信息,UIImage的imageOrientation属性指的就是EXIF中的orientation信息.如果我们忽略orientation信心,而直接对照片进行想速处 ...
- 修正iOS从照相机和相册中获取的图片方向(转)
- (UIImage *)fixOrientation { // No-op if the orientation is already correct if (self.imageOrientati ...
- (转)如何处理iOS中照片的方向
如何处理iOS中照片的方向 31 May 2015 • 7 min. read • Comments 使用过iPhone或者iPad的朋友在拍照时不知是否遇到过这样的问题,将设备中的照片导出到Wind ...
- UIImageView 动画 / UIImage 方向
UIImage 方向 UIImage imageOrientation是相对当前屏幕的横竖屏来判断方向 如果本身是横屏, 照片也是横屏的话, 方向是正方向 BOOL b1 = (originalIma ...
- iOS开发中图片方向的获取与更改
iOS开发中 再用到照片的时候 或多或少遇到过这样的问题 就是我想用的照片有横着拍的有竖着排的 所以导致我选取图片后的效果也横七竖八的 显示效果不好 比如: 图中红圈选中的图片选取的是横着拍 ...
- 修正iOS从照相机和相册中获取的图片方向
使用系统相机拍照得到的图片的默认方向有时不是ImageOrientationDown,而是ImageOrientationLeft,在使用的时候会出现图片顺时针偏转90°.使用fixOrientati ...
- 转:iPhone上关于相机拍照的图片的imageOrientation的问题
用相机拍摄出来的照片含有EXIF信息,UIImage的imageOrientation属性指的就是EXIF中的orientation信息.如果我们忽略orientation信息,而直接对照片进行像素处 ...
- DICOM中几个判断图像方向的tag
在DICOM标准里,有三个TAG与成像的方向相关. 参考来源:Kitware关于DICOM方向的说明 http://public.kitware.com/IGSTKWIKI/index.php/DIC ...
随机推荐
- LL LR SLR LALR 傻傻分不清
[转] 一:LR(0),SLR(1),规范LR(1),LALR(1)的关系 首先LL(1)分析法是自上而下的分析法.LR(0),LR(1),SLR(1),LALR(1)是自下而上的分析法. ...
- iOS 琐碎点------切某个或某几个角的圆角
不说废话----------> 1.如果是切四个角的圆角,代码示例: self.picImage.layer.cornerRadius = 8; self.picImage.layer.mask ...
- Unity之CharacterController 碰撞问题总结
CharacterController 不会受到scene的重力影响,自带物理碰撞检测,在脱离导航网格的应用场景下(比如飞行),是很有优势的Unity原生工具组件.如果在复杂的应用场景里,会有多种CC ...
- navicat 结合快捷键
ctrl+q 打开查询窗口ctrl+/ 注释sql语句ctrl+shift +/ 解除注释ctrl+r 运行查询窗口的sql语句ctrl+shift+r 只运行选中的sql语句F6 打开一个mysql ...
- MySQL主从复制技术的简单实现
配置环境: 主从服务器操作系统均为 ubuntu15.10 主从服务器MySQL版本均为 MySQL5.6.31 主服务器IP:192.168.0.178 从服务器IP:192.168.0.145 主 ...
- 纯命令行的编辑利器:用好 awk 与 sed
awk 的基本语法 awk 是模式查找与处理语言,是文本处理的利器.使用 awk 可以只用一条简单的命令完成复杂的文本数据处理. awk 命令的基本结构为: awk '模式 {处理}' 文件 比如,打 ...
- Linux 挂载管理(mount)
标签:mount,umount 概述 在上一章增加linux操作系统空间中已经使用过了mount命令对分区进行挂载,这一章详细介绍挂载管理,该命令涉及的知识点也挺多的而且也还比较重要,是需要掌握的一个 ...
- [ASP.NET MVC 小牛之路]16 - Model 验证
上一篇博文 [ASP.NET MVC 小牛之路]15 - Model Binding 中讲了MVC在Model Binding过程中如何根据用户提交HTTP请求数据创建Model对象.在实际的项目中, ...
- 如何在 ASP.NET MVC 中集成 AngularJS(3)
今天来为大家介绍如何在 ASP.NET MVC 中集成 AngularJS 的最后一部分内容. 调试路由表 - HTML 缓存清除 就在我以为示例应用程序完成之后,我意识到,我必须提供两个版本的路由表 ...
- eclipse启动时报告错误:Java was started but returned exit code=-805306369
这两天也没改过eclipse和java的配置,但eclipse启动时报告错误:Java was started but returned exit code=-805306369 后来在eclipse ...