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 ...
随机推荐
- 公司培训 oracle( 第一天)
以前在学校学习Oracle的时候就对rowid 和rownum 这两个伪列有很大的疑惑,今天公司对16届新员工进行公司内部技术培训,课堂上的讲解,又让我想起来了曾经的疑惑点, 我想不能在让这个疑惑继续 ...
- java的jxl技术导入Excel
项目结构: http://www.cnblogs.com/hongten/gallery/image/112177.html 在项目中我们看到Reference Libraries中的jxl.jar包 ...
- SQLServer存储过程事务用法
更多资源:http://denghejun.github.io IF object_id('InsertAntennaProcedure') IS NOT NULL DROP PROCEDURE In ...
- SQL Server2005清除数据库日志
SQL2005清空删除日志: 复制代码 代码如下: Backup Log DNName with no_log '这里的DNName是你要收缩的数据库名,自己注意修改下面的数据库名,我就不再注释了 ...
- 初探ReactJS.NET 开发
ReactJS通常也被称为"React",是一个刚刚在这场游戏中登场的新手.它由Facebook创建,并在2013年首次发布.Facebook认为React在处理SPA问题上可以成 ...
- ASP.NET SignalR 高可用设计
在 One ASP.NET 的架构图中,微软将 WebAPI 和 SignalR 归类到 Services 类型与 MVC.Web Forms 同列为一等公民,未来的 ASP.NET 5 尽管还在be ...
- Java NIO5:选择器1---理论篇
选择器 最后,我们探索一下选择器.由于选择器内容比较多,所以本篇先偏理论地讲一下,后一篇讲代码,文章也没有什么概括.总结的,写到哪儿算哪儿了,只求能将选择器写明白,并且将一些相对重要的内容加粗标红. ...
- 一起学习jQuery2.0.3源码—1.开篇
write less,do more jQuery告诉我们:牛逼的代码不仅精简而且高效! 2006年1月由美国人John Resig在纽约的barcamp发布了jQuery,吸引了来自世界各地众多Ja ...
- 用python实现的百度音乐下载器-python-pyqt-改进版
之前写过一个用python实现的百度新歌榜.热歌榜下载器的博文,实现了百度新歌.热门歌曲的爬取与下载.但那个采用的是单线程,网络状况一般的情况下,扫描前100首歌的时间大概得到40来秒.而且用Pyqt ...
- 《Entity Framework 6 Recipes》中文翻译系列 (41) ------ 第七章 使用对象服务之标识关系中使用依赖实体与异步查询保存
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-7 标识关系中使用依赖实体 问题 你想在标识关系中插入,更新和删除一个依赖实体 ...