iOS开发中关于UIImage的知识点总结
UIImage是iOS中层级比较高的一个用来加载和绘制图像的一个类,更底层的类还有 CGImage,以及iOS5.0以后新增加的CIImage。今天我们主要聊一聊UIImage的三个属性: imageOrientation, size, scale,几个初始化的方法: imageNamed,imageWithContentsOfFile,以及绘制Image的几个draw开头的方法。 AD:51CTO 网+ 第十二期沙龙:大话数据之美_如何用数据驱动用户体验 UIImage是iOS中层级比较高的一个用来加载和绘制图像的一个类,更底层的类还有 CGImage,以及iOS5.0以后新增加的CIImage。今天我们主要聊一聊UIImage的三个属性: imageOrientation, size, scale,几个初始化的方法: imageNamed,imageWithContentsOfFile,以及绘制Image的几个draw开头的方法。 一、UIImage的size,scale属性 先想一个问题“一个图像的尺寸到底是多大呢?” 第一反应可能就是image.size,恭喜你答错了,正确的答案是图像的实际的尺寸(像 素)等于image.size乘以image.scale。如果做过界面贴图的话你可能经常会需要准备至少两套图,一套1倍图,一套图已@2x命名的二倍 图。这样当我们的程序运行在retina屏幕的时候系统就会自动的去加载@2x的图片,它的size将和一倍图加载进来的size相等,但是scale却 置为2,这点大家可以做个简单的小测试验证一下。然我们再深入一点儿为什么不直接加载到成二倍的尺寸呢,原因很简单因为我们在界面布局中逻辑坐标系中的 (单位是point),而实际的绘制都是在设备坐标系(单位是pixel)进行的,系统会自动帮我们完成从point到pixel之间的转化。其实这个比 例也就刚好和UIScreen中的scale对应,这样整条scale的线就可以串通了。 二、UIImage的几种初始化方法的对比 、imageNamed:方法 imageNamed:是UIImage的一个类方法,它做的事情比我们看到的要稍微多一些。它的加载流程如下: a. 系统回去检查系统缓存中是否存在该名字的图像,如果存在则直接返回。 b. 如果系统缓存中不存在该名字的图像,则会先加载到缓存中,在返回该对象。 观察上面的操作我们发现系统会缓存我们使用imageNamed:方法加载的图像时候,系统会自动帮我们缓存。这种机制适合于那种频繁用到界面贴图累的加载,但如果我们需要短时间内频繁的加载一些一次性的图像的话,最好不要使用这种方法。 、imageWithContentsOfFile:和initWithContentsOfFile:方法 这两个方法跟前一个方法一样都是完成从文件加载图像的功能。但是不会经过系统缓存,直接从文件系统中加载并返回。 顺便提一下,当收到内存警告的时候,系统可能会将UIImage内部的存储图像的内存释放,下一次需要绘制的时候会重新去加载。 、imageWithCGImage:scale:orientation:方法 该方面使用一个CGImageRef创建UIImage,在创建时还可以指定方法倍数以及旋转方向。当scale设置为1的时候,新创建的图像将和原图像尺寸一摸一样,而orientaion则可以指定新的图像的绘制方向。 三、UIImage的imageOrientation属性 UIImage有一个imageOrientation的属性,主要作用是控制image的绘制方向,共有以下8中方向: typedef NS_ENUM(NSInteger, UIImageOrientation) {
UIImageOrientationUp, // default orientation
UIImageOrientationDown, // 180 deg rotation
UIImageOrientationLeft, // 90 deg CCW (编程发现官方文档中,left和right图像标反了,此处更正过来)
UIImageOrientationRight, // 90 deg CW
UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip
UIImageOrientationDownMirrored, // horizontal flip
UIImageOrientationLeftMirrored, // vertical flip
UIImageOrientationRightMirrored, // vertical flip
}; 默认的方向是UIImageOrientationUp,这8种方向对应的绘制方如上面所示。我 们在日常使用中经常会碰到把iPhone相册中的照片导入到windows中,发现方向不对的问题就是与这个属性有关,因为导出照片的时候,写exif中 的方向信息时候没有考虑该方向的原因。既然这个属性可以控制image的绘制方向,那我们能不能通过改过这个属性来完成UIImage的旋转和翻转呢?带 着这个问题我们继续往下看。 四、UIImage的几个draw方法 UIImage的几个draw方法是用来绘制图像的利器,为什么这样说呢?因为它们在绘制图 像的时候会考虑当前图像的方向,即根据的imageOrientation绘制出不同的方向。由于图像是绘制在当前context中的,它同时还会考虑到 当前context的transform的变化。利于这两点我们就可以玩转图像的旋转和翻转了。 搜索了一些,目前网上大部分图像旋转都是通过创建CGBitmapContext,然后根据图像方向设置context的transform来实现的,这种方法要求对整个矩阵变化的过程都非常清楚,一个参数设置不多,出来的结果就会有问题。 下面我介绍一种实现起来简单方便的图像旋转方法,这种方法主要就是利用imageWithCGImage:scale:orientation:方法,指定不同的orientation来完成所需要的功能,先举个简单的例子: 假设一副图片显示为 iOS开发中关于UIImage的知识点 - 第1张 | IT江湖,我们要向左旋转90°,那么转过之后应该就会显示为iOS开发中关于UIImage的知识点 - 第2张 | IT江湖,即将原图从orientationUP转到orientationLeft即可。以此类推为不同的方向旋转,只需要注意看R的显示即可,这样整个旋转和翻转的实现过程中完全可以不用考虑Transform那些东西,是不是很简单。 下面是图像旋转和翻转的完整代码: //
// UIImage+Rotate_Flip.h
// SvImageEdit
//
// Created by maple on 5/14/13.
// Copyright (c) 2013 smileEvday. All rights reserved.
//
// #import <UIKit/UIKit.h> @interface UIImage (Rotate_Flip) /*
* @brief rotate image 90 withClockWise
*/
- (UIImage*)rotate90Clockwise; /*
* @brief rotate image 90 counterClockwise
*/
- (UIImage*)rotate90CounterClockwise; /*
* @brief rotate image 180 degree
*/
- (UIImage*)rotate180; /*
* @brief rotate image to default orientation
*/
- (UIImage*)rotateImageToOrientationUp; /*
* @brief flip horizontal
*/
- (UIImage*)flipHorizontal; /*
* @brief flip vertical
*/
- (UIImage*)flipVertical; /*
* @brief flip horizontal and vertical
*/
- (UIImage*)flipAll; @end UIImage+Rotate_Flip.h //
// UIImage+Rotate_Flip.m
// SvImageEdit
//
// Created by maple on 5/14/13.
// Copyright (c) 2013 smileEvday. All rights reserved.
// #import "UIImage+Rotate_Flip.h" @implementation UIImage (Rotate_Flip) /*
* @brief rotate image 90 with CounterClockWise
*/
- (UIImage*)rotate90CounterClockwise
{
UIImage *image = nil;
switch (self.imageOrientation) {
case UIImageOrientationUp:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeft];
break;
}
case UIImageOrientationDown:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRight];
break;
}
case UIImageOrientationLeft:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDown];
break;
}
case UIImageOrientationRight:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUp];
break;
}
case UIImageOrientationUpMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRightMirrored];
break;
}
case UIImageOrientationDownMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeftMirrored];
break;
}
case UIImageOrientationLeftMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUpMirrored];
break;
}
case UIImageOrientationRightMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDownMirrored];
break;
}
default:
break;
} return image;
} /*
* @brief rotate image 90 with Clockwise
*/
- (UIImage*)rotate90Clockwise
{
UIImage *image = nil;
switch (self.imageOrientation) {
case UIImageOrientationUp:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRight];
break;
}
case UIImageOrientationDown:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeft];
break;
}
case UIImageOrientationLeft:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUp];
break;
}
case UIImageOrientationRight:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDown];
break;
}
case UIImageOrientationUpMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeftMirrored];
break;
}
case UIImageOrientationDownMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRightMirrored];
break;
}
case UIImageOrientationLeftMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDownMirrored];
break;
}
case UIImageOrientationRightMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUpMirrored];
break;
}
default:
break;
} return image;
} /*
* @brief rotate image 180 degree
*/
- (UIImage*)rotate180
{
UIImage *image = nil;
switch (self.imageOrientation) {
case UIImageOrientationUp:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDown];
break;
}
case UIImageOrientationDown:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUp];
break;
}
case UIImageOrientationLeft:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRight];
break;
}
case UIImageOrientationRight:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeft];
break;
}
case UIImageOrientationUpMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDownMirrored];
break;
}
case UIImageOrientationDownMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUpMirrored];
break;
}
case UIImageOrientationLeftMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRightMirrored];
break;
}
case UIImageOrientationRightMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeftMirrored];
break;
}
default:
break;
} return image;
} /*
* @brief rotate image to default orientation
*/
- (UIImage*)rotateImageToOrientationUp
{
CGSize size = CGSizeMake(self.size.width * self.scale, self.size.height * self.scale);
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, CGRectMake(, , size.width, size.height)); [self drawInRect:CGRectMake(, , size.width, size.height)]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); return image;
} /*
* @brief flip horizontal
*/
- (UIImage*)flipHorizontal
{
UIImage *image = nil;
switch (self.imageOrientation) {
case UIImageOrientationUp:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUpMirrored];
break;
}
case UIImageOrientationDown:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDownMirrored];
break;
}
case UIImageOrientationLeft:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRightMirrored];
break;
}
case UIImageOrientationRight:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeftMirrored];
break;
}
case UIImageOrientationUpMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUp];
break;
}
case UIImageOrientationDownMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDown];
break;
}
case UIImageOrientationLeftMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRight];
break;
}
case UIImageOrientationRightMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeft];
break;
}
default:
break;
} return image;
} /*
* @brief flip vertical
*/
- (UIImage*)flipVertical
{
UIImage *image = nil;
switch (self.imageOrientation) {
case UIImageOrientationUp:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDownMirrored];
break;
}
case UIImageOrientationDown:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUpMirrored];
break;
}
case UIImageOrientationLeft:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeftMirrored];
break;
}
case UIImageOrientationRight:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRightMirrored];
break;
}
case UIImageOrientationUpMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationDown];
break;
}
case UIImageOrientationDownMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationUp];
break;
}
case UIImageOrientationLeftMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationLeft];
break;
}
case UIImageOrientationRightMirrored:
{
image = [UIImage imageWithCGImage:self.CGImage scale: orientation:UIImageOrientationRight];
break;
}
default:
break;
} return image;
} /*
* @brief flip horizontal and vertical
*/
- (UIImage*)flipAll
{
return [self rotate180];
} @end UIImage+Rotate_Flip.m 以上只是实现了图像的顺时针90°,逆时针90°,°旋转,以及水平翻转,数值翻转等。至 于任意角度旋转怎么实现?其实也很简单,留着给大家思考吧。虽然我们可以通过orientation这种方法简单的完成图像旋转,但是如果有时间的话还是 建议大家尽量的看一下那种通过transform来完成旋转的代码,你会彻底搞清楚旋转矩阵是怎么回事儿。当然程序中使用的时候推荐使用我上面提供的这种 方法,因为不涉及真实的旋转操作,速度会快很多。 通过上面的小例子,我们可以看出越高级别的API帮助我们做的事情就越多,越底层的API提 供了更多的灵活性,但同时也带来了很多需要我们处理的东西。再编程的过程中尽量的使用高级别的API,同时最好能搞懂底层的实现机制。这样我们的程序才会 更高效,出了问题才知道去哪里查找。 来自www.cnblogs.com/smileEvday/archive////UIImage.html
iOS开发中关于UIImage的知识点总结的更多相关文章
- Hybrid App 应用开发中 9 个必备知识点复习(WebView / 调试 等)
前言 我们大前端团队内部 ?每周一练 的知识复习计划继续加油,本篇文章是 <Hybrid APP 混合应用专题> 主题的第二期和第三期的合集. 这一期共整理了 10 个问题,和相应的参考答 ...
- ios开发中的小技巧
在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...
- iOS开发UI篇—iOS开发中三种简单的动画设置
iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView b ...
- iOS开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】
在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运 ...
- iOS开发中的4种数据持久化方式【一、属性列表与归档解档】
iOS中的永久存储,也就是在关机重新启动设备,或者关闭应用时,不会丢失数据.在实际开发应用时,往往需要持久存储数据的,这样用户才能在对应用进行操作后,再次启动能看到自己更改的结果与痕迹.ios开发中, ...
- 多线程在iOS开发中的应用
多线程基本概念 01 进程 进程是指在系统中正在运行的一个应用程序.每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 02 线程 2-1 基本概念 1个进程要想执行任务,必须得有线程 ...
- iOS开发中你是否遇到这些经验问题
前言 小伙伴们在开发中难免会遇到问题, 你是如何解决问题的?不妨也分享给大家!如果此文章其中的任何一条问题对大家有帮助,那么它的存在是有意义的! 反正不管怎样遇到问题就要去解决问题, 在解决问题的同时 ...
- 深入理解 iOS 开发中的锁
来源:伯乐在线 - 夏天然后 链接:http://ios.jobbole.com/89474/ 点击 → 申请加入伯乐在线专栏作者 摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大 ...
- 如何在IOS开发中在自己的framework中添加.bunble文件
今天就跟大家介绍一下有关,如何在IOS开发中在自己的framework中添加.bunble文件,该文章我已经在IOS教程网(http://ios.662p.com)发布过来,个人觉得还是对大家有帮助的 ...
随机推荐
- phpmyadmin数据导入最大限制的解决方法
mysql导入文件最大限制更改解决方法:phpmyadmin库导入出错:You probably tried to upload too large file. Please refer to doc ...
- php引用(&)详解及注意事项
php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容,在内存中存 ...
- thinkphp3.2 namespace及use用法
PHP 5.3中的namespace其实是个不错的东西,可以简化编程,下面介绍三类在代码中 访问namespace中类的方法 1 引用namespace和类 假设namespace的程序为name ...
- "The connection for the USB device '###' was unsuccessful. The device is currently in use"
一.问题描述 1.情景描述 笔者的物理主机系统是“windows7 64位”,想使用“摄像头录像大师”.这个软件在录制视频的过程中,需要调用windows自带的"windows media ...
- 通过阅读ASP.NET MVC5 框架解密 路由的一点心得
路由: 1.在ASP.NET中路由不专属与ASP.NET MVC,因为路由(Route)是在system.web 命名空间下的,所以传统的WebForm也可以使用路由. 2.什么叫做路由 采用某种机制 ...
- GMM+Kalman Filter+Blob 目标跟踪
转 http://www.cnblogs.com/YangQiaoblog/p/5462453.html ==========图片版================================== ...
- activity学习(1) 生命周期理解
可以忽略onWindowFocusChanged.onSaveInstanceState.onRestoreInstanceState几个事件,这几个事件官网中的生命周期里面没有提到.忽略掉这几个方法 ...
- OpenCV for c++Builder
整理日: 20154/6 Borland C++BuilderでOpenCVを使う 確認 Turbo C++ 2007/03 1. ダウンロード&インストール http://sourcefor ...
- hibernate中的缓存机制
一.为什么要用Hibernate缓存? Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源中的数 ...
- bzoj 2594: [Wc2006]水管局长数据加强版 动态树
2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 934 Solved: 291[Submit][Sta ...