iOS开发中关于UIImage的知识点总结

移动开发 iOS
UIImage是iOS中层级比较高的一个用来加载和绘制图像的一个类,更底层的类还有 CGImage,以及iOS5.0以后新增加的CIImage。今天我们主要聊一聊UIImage的三个属性: imageOrientation, size, scale,几个初始化的方法: imageNamed,imageWithContentsOfFile,以及绘制Image的几个draw开头的方法。

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的几种初始化方法的对比

1、imageNamed:方法

imageNamed:是UIImage的一个类方法,它做的事情比我们看到的要稍微多一些。它的加载流程如下:

a. 系统回去检查系统缓存中是否存在该名字的图像,如果存在则直接返回。

b. 如果系统缓存中不存在该名字的图像,则会先加载到缓存中,在返回该对象。

观察上面的操作我们发现系统会缓存我们使用imageNamed:方法加载的图像时候,系统会自动帮我们缓存。这种机制适合于那种频繁用到界面贴图累的加载,但如果我们需要短时间内频繁的加载一些一次性的图像的话,***不要使用这种方法。

2、imageWithContentsOfFile:和initWithContentsOfFile:方法

这两个方法跟前一个方法一样都是完成从文件加载图像的功能。但是不会经过系统缓存,直接从文件系统中加载并返回。

顺便提一下,当收到内存警告的时候,系统可能会将UIImage内部的存储图像的内存释放,下一次需要绘制的时候会重新去加载。

3、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  
}; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

默认的方向是UIImageOrientationUp,这8种方向对应的绘制方如上面所示。我 们在日常使用中经常会碰到把iPhone相册中的照片导入到windows中,发现方向不对的问题就是与这个属性有关,因为导出照片的时候,写exif中 的方向信息时候没有考虑该方向的原因。既然这个属性可以控制image的绘制方向,那我们能不能通过改过这个属性来完成UIImage的旋转和翻转呢?带 着这个问题我们继续往下看。

四、UIImage的几个draw方法

UIImage的几个draw方法是用来绘制图像的利器,为什么这样说呢?因为它们在绘制图 像的时候会考虑当前图像的方向,即根据的imageOrientation绘制出不同的方向。由于图像是绘制在当前context中的,它同时还会考虑到 当前context的transform的变化。利于这两点我们就可以玩转图像的旋转和翻转了。

搜索了一些,目前网上大部分图像旋转都是通过创建CGBitmapContext,然后根据图像方向设置context的transform来实现的,这种方法要求对整个矩阵变化的过程都非常清楚,一个参数设置不多,出来的结果就会有问题。

下面我介绍一种实现起来简单方便的图像旋转方法,这种方法主要就是利用imageWithCGImage:scale:orientation:方法,指定不同的orientation来完成所需要的功能,先举个简单的例子:

假设一副图片显示为 [[114093]],我们要向左旋转90°,那么转过之后应该就会显示为[[114094]],即将原图从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 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
// 
//  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:1 orientation:UIImageOrientationLeft]; 
            break
        } 
        case UIImageOrientationDown: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRight]; 
            break
        } 
        case UIImageOrientationLeft: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationDown]; 
            break
        } 
        case UIImageOrientationRight: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUp]; 
            break
        } 
        case UIImageOrientationUpMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRightMirrored]; 
            break
        } 
        case UIImageOrientationDownMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationLeftMirrored]; 
            break
        } 
        case UIImageOrientationLeftMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUpMirrored]; 
            break
        } 
        case UIImageOrientationRightMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 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:1 orientation:UIImageOrientationRight]; 
            break
        } 
        case UIImageOrientationDown: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationLeft]; 
            break
        } 
        case UIImageOrientationLeft: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUp]; 
            break
        } 
        case UIImageOrientationRight: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationDown]; 
            break
        } 
        case UIImageOrientationUpMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationLeftMirrored]; 
            break
        } 
        case UIImageOrientationDownMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRightMirrored]; 
            break
        } 
        case UIImageOrientationLeftMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationDownMirrored]; 
            break
        } 
        case UIImageOrientationRightMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 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:1 orientation:UIImageOrientationDown]; 
            break
        } 
        case UIImageOrientationDown: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUp]; 
            break
        } 
        case UIImageOrientationLeft: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRight]; 
            break
        } 
        case UIImageOrientationRight: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationLeft]; 
            break
        } 
        case UIImageOrientationUpMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationDownMirrored]; 
            break
        } 
        case UIImageOrientationDownMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUpMirrored]; 
            break
        } 
        case UIImageOrientationLeftMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRightMirrored]; 
            break
        } 
        case UIImageOrientationRightMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 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(0, 0, size.width, size.height)); 
     
    [self drawInRect:CGRectMake(0, 0, 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:1 orientation:UIImageOrientationUpMirrored]; 
            break
        } 
        case UIImageOrientationDown: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationDownMirrored]; 
            break
        } 
        case UIImageOrientationLeft: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRightMirrored]; 
            break
        } 
        case UIImageOrientationRight: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationLeftMirrored]; 
            break
        } 
        case UIImageOrientationUpMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUp]; 
            break
        } 
        case UIImageOrientationDownMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationDown]; 
            break
        } 
        case UIImageOrientationLeftMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRight]; 
            break
        } 
        case UIImageOrientationRightMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 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:1 orientation:UIImageOrientationDownMirrored]; 
            break
        } 
        case UIImageOrientationDown: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUpMirrored]; 
            break
        } 
        case UIImageOrientationLeft: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationLeftMirrored]; 
            break
        } 
        case UIImageOrientationRight: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRightMirrored]; 
            break
        } 
        case UIImageOrientationUpMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationDown]; 
            break
        } 
        case UIImageOrientationDownMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUp]; 
            break
        } 
        case UIImageOrientationLeftMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationLeft]; 
            break
        } 
        case UIImageOrientationRightMirrored: 
        { 
            image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRight]; 
            break
        } 
        default
            break
    } 
     
    return image; 

  
/* 
* @brief flip horizontal and vertical 
*/ 
- (UIImage*)flipAll 

    return [self rotate180]; 

  
@end 
  
UIImage+Rotate_Flip.m 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.

以上只是实现了图像的顺时针90°,逆时针90°,180°旋转,以及水平翻转,数值翻转等。至 于任意角度旋转怎么实现?其实也很简单,留着给大家思考吧。虽然我们可以通过orientation这种方法简单的完成图像旋转,但是如果有时间的话还是 建议大家尽量的看一下那种通过transform来完成旋转的代码,你会彻底搞清楚旋转矩阵是怎么回事儿。当然程序中使用的时候推荐使用我上面提供的这种 方法,因为不涉及真实的旋转操作,速度会快很多。

通过上面的小例子,我们可以看出越高级别的API帮助我们做的事情就越多,越底层的API提 供了更多的灵活性,但同时也带来了很多需要我们处理的东西。再编程的过程中尽量的使用高级别的API,同时***能搞懂底层的实现机制。这样我们的程序才会 更高效,出了问题才知道去哪里查找。

来自www.cnblogs.com/smileEvday/archive/2013/05/14/UIImage.html

责任编辑:闫佳明 来源: itjhwd
相关推荐

2009-08-06 17:42:32

C#知识点

2016-12-21 09:55:55

面试JavaScrip总结

2013-01-06 09:52:43

SQLite

2013-04-09 16:04:06

iOS开发SQLite知识总结

2010-08-18 10:52:46

Linux笔试

2010-06-17 16:42:04

UML

2020-07-01 17:25:28

Redis数据库内存

2020-12-28 08:13:01

前端开发技术热点

2020-12-28 08:16:30

前端开发技术热点

2022-07-20 00:15:48

SQL数据库编程语言

2015-04-21 09:28:29

2020-12-24 13:32:31

大数据数据分析SQL

2017-12-08 14:26:19

Android面试知识点总结

2021-04-13 08:25:12

测试开发Java注解Spring

2014-03-12 10:13:00

iOSSEL对象

2012-04-23 15:49:04

2020-06-19 16:25:19

MySQL日志文件数据库

2022-08-16 15:17:37

机器学习算法模型

2023-12-15 08:07:37

响应式布局官网

2021-06-29 15:56:39

MYSQL开发数据库
点赞
收藏

51CTO技术栈公众号