resizableImageWithCapInsets:方法的探析 (转载笔记)

resizableImageWithCapInsets:方法的探析测试

 

 做者 SketchK七爷 atom

1. 故事背景spa

苹果公司为iOS开发者提供了如下的方法用于处理图片的拉伸问题.net

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode设计

//为行文方便,以后简称该方法为拉伸方法对象

但在实际使用过程当中,我发现本身对该方法的理解不够深刻,因此今天特意编写了一些代码来探析该方法!图片

好了,废话很少说,下面咱们就开始探析该方法的奥妙吧!开发

2. 方法介绍和说明get

-(UIImage*)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingModeit

//该方法返回的是UIImage类型的对象,即返回经该方法拉伸后的图像

//传入的第一个参数capInsets是UIEdgeInsets类型的数据,即原始图像要被保护的区域

//这个参数是一个结构体,定义以下

//typedef struct { CGFloat top, left , bottom, right ; } UIEdgeInsets;

//该参数的意思是被保护的区域到原始图像外轮廓的上部,左部,底部,右部的直线距离,参考图2.1

//传入的第二个参数resizingMode是UIImageResizingMode相似的数据,即图像拉伸时选用的拉伸模式,

//这个参数是一个枚举类型,有如下两种方式

//UIImageResizingModeTile,     平铺 

//UIImageResizingModeStretch,  拉伸

图2.1 capInsets 参数示意图.png

 

3. 设计实验方法

实验对象

Image对象尺寸为60*128(为行文方便,以后简称为原始图像,图3.1)

ImageView对象尺寸为180*384(为行文方便,以后简称为相框)

        

图3.1 原始图像.png

 

实验方法

  1. 对原始图像使用拉伸方法并输入不一样的参数
  2. 将拉伸后的图像放入相框,观察其拉伸效果

测试软件的界面设计

界面设计如图3.2

正上方为原始图像窗口,用于显示原始图像的效果

左下方为测试图像窗口,用于显示测试情况的效果

右下方为对比图像窗口,用于显示默认情况的效果

图3.2 测试软件的界面设计.png

 

 

4.实验分析

4.1 拉伸模式

resizingMode参数为UIImageResizingModeStretch

4.1.1.capInsets参数为UIEdgeInsetsMake(0, 0, 0, 0)时

当咱们向拉伸方法传入该组参数时,表明咱们未对原始图像的任何区域进行保护.其拉伸效果如图4.1.1

在该种状况下,咱们发现原始图像按比例放大了3倍,所以咱们将该状况当作拉伸模式下的默认情况

在以后的实验中,咱们将该种情况当作参考对象,显示在界面的右下角

 

图4.1.1 测试结果1.png

 

4.1.2.capInsets参数为UIEdgeInsetsMake(42, 0, 0, 0)时

当咱们向拉伸方法传入该组参数时,表明咱们对原始图像上部的三分之一进行保护(即红色方块区域).其拉伸效果如图4.1.2

在该种状况下,咱们能够发现拉伸后的图像中:

  • 原始图像中受保护的区域(即红色方块区域)在Y轴方向保持了原比例,但在X轴方向进行了拉伸
  • 原始图像中未受保护的区域,直接按比例进行了拉伸

图4.1.2 测试结果2.png

 

 

4.1.3.capInsets参数为UIEdgeInsetsMake(0,20, 0, 0)时

当咱们向拉伸方法传入该组参数时,表明咱们对原始图像左部的三分之一进行保护(即红色方块区域).其拉伸效果如图4.1.3

在该种状况下,咱们能够发现拉伸后的图像中:

  • 原始图像中受保护的区域(即红色方块区域)在X轴方向保持了原比例,但在Y轴方向进行了拉伸
  • 原始图像中未受保护的区域,直接按比例进行了拉伸

图4.1.3 测试结果3.png

 

 

4.1.4.capInsets参数为UIEdgeInsetsMake(42, 20, 42, 20)时

当咱们向拉伸方法传入该组参数时,表明咱们对原始图像除数字5之外的区域进行保护(即两个红色方块围起来的区域).其拉伸效果如图4.1.4

在该种状况下,咱们能够发现拉伸后的图像中:

  • 在X轴上,因为1被左边和上边的设置保护,3被右边和上边的设置保护,因此只能用中间的2来拉伸,同理最底下的7,8,9
  • 在Y轴上,因为1被左边和上边的设置保护,7被左边和下边的设置保护,因此只能用中间的4来拉伸,同理最底下的3,6,9
  • 因为5没有被保护,因此在整个剩余的空间中,用5进行拉伸填充

图4.1.4 测试结果4.png

 

 

4.2选择平铺模式

resizingMode参数为UIImageResizingModeTile

4.2.1.capInsets参数为UIEdgeInsetsMake(0, 0, 0, 0)时

当咱们向拉伸方法传入该组参数时,表明咱们未对原始图像的任何区域进行保护.其平铺效果如图4.2.1

在该种状况下,咱们发现原始图像按比例填充了相框,所以咱们将该状况当作拉伸模式下的默认情况

在以后的实验中,咱们将该种情况当作参考对象,显示在界面的右下角

图4.2.1 测试结果1.png

 

4.2.2.capInsets参数为UIEdgeInsetsMake(42, 0, 0, 0)时

当咱们向拉伸方法传入该组参数时,表明咱们对原始图像上部的三分之一进行保护(即红色方块区域).其平铺效果如图4.2.2

在该种状况下,咱们能够发现拉伸后的图像中:

  • 原始图像中受保护的区域(即红色方块区域)在Y轴方向保持了原比例,但在X轴方向进行了平铺填充
  • 原始图像中未受保护的区域,直接按比例进行了平铺,但不包含被保护的区域(注意观察蓝色箭头所指的区域)

图4.2.2 测试结果1.png

 

4.2.3.capInsets参数为UIEdgeInsetsMake(0,20, 0, 0)时

当咱们向拉伸方法传入该组参数时,表明咱们对原始图像左部的三分之一进行保护(即红色方块区域).其平铺效果如图4.2.3

在该种状况下,咱们能够发现拉伸后的图像中:

  • 原始图像中受保护的区域(即红色方块区域)在X轴方向保持了原比例,但在Y轴方向进行了平铺填充
  • 原始图像中未受保护的区域,直接按比例进行了平铺,但不包含被保护的区域(注意观察蓝色箭头所指的区域)

图4.2.3 测试结果3.png

 

4.2.4.capInsets参数为UIEdgeInsetsMake(42, 20, 42, 20)时

当咱们向拉伸方法传入该组参数时,表明咱们对原始图像除数字5之外的区域进行保护(即两个红色方块围起来的区域).其拉伸效果如图4.2.4

在该种状况下,咱们能够发现拉伸后的图像中:

  • 在X轴上,因为1被左边和上边的设置保护,3被右边和上边的设置保护,因此只能用中间的2来平铺,同理最底下的7,8,9
  • 在Y轴上,因为1被左边和上边的设置保护,7被左边和下边的设置保护,因此只能用中间的4来平铺,同理最底下的3,6,9
  • 因为5没有被保护,因此在整个剩余的空间中,用5进行平铺填充

图4.2.4 测试结果4.png

 

5. 结论和建议

经过8组实验数据能够观察出拉伸方法在平铺模式和拉伸模式下的变化过程和主要区别,由此咱们可知:

  • 对原始图形使用拉伸方法且在四周增长保护区域后,能保证原始图形的四个角不失真,但其他部分的变化细节则有不一样
  • 若是原始图像的外轮廓不平整的话,使用拉伸方式会让外轮廓的不平整度放大,使用平铺方式应该能减少这种状况

6. 附录-代码

为了缩短代码的长度,我使用了Storyboard搭建软件界面,想重现实验的朋友能够自行构建界面,具体的参数我在文章和附录中进行了简要说明,我相信聪明的你必定能够搞定!

#import "ViewController.h"

 

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *imageView1;

@property (weak, nonatomic) IBOutlet UIImageView *imageView2;

@property (weak, nonatomic) IBOutlet UIImageView *imageView3;

@end

 

@implementation ViewController

 

- (void)viewDidLoad {

[super viewDidLoad];

 

//--imageView1的相关内容------------------------------------------------------------------------------------

 

//相框大小为60 * 128    图片尺寸为60 * 128

//读取图片

UIImage *testImage1 = [UIImage imageNamed:@"123456789"];

 

testImage1 = [testImage1 resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeStretch];

self.imageView1.image = testImage1;

 

//---imageView2的相关内容-----------------------------------------------------------------------------------

 

//相框为180 * 384    图片尺寸为60 * 128    相框大小为原始图片的3倍

//读取图片

UIImage *testImage2 = [UIImage imageNamed:@"123456789"];

/***********************************************/

//方法1 resizableImageWithCapInsets:默认是平铺

//方法2 resizableImageWithCapInsets: resizingMode: 方法

//  UIImageResizingModeTile,     平铺

//平铺的概念是保证原图像大小不变,将新图像填充满

//testImage2 = [testImage2 resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeTile];

 

//将上部的三分之一"保护",而后进行显示

//这表明新图像中,上部的三分之一和原图像同样,而其他部分的填充不会使用原图像上部的三分之一

// testImage2 = [testImage2 resizableImageWithCapInsets:UIEdgeInsetsMake(42, 0, 0, 0) resizingMode:UIImageResizingModeTile];

 

//将左部的三分之一"保护",而后进行显示

//这表明新图像中,上部的三分之一和原图像同样,而其他部分的填充不会使用原图像上部的三分之一

// testImage2 = [testImage2 resizableImageWithCapInsets:UIEdgeInsetsMake(0,20, 0, 0) resizingMode:UIImageResizingModeTile];

 

//将四周进行保护后

//在X轴上,因为1被左边的设置保护,3被右边的设置保护,因此中间只能用2来平铺,同理,7和9之间的8

//在Y轴上,因为1被上边的设置保护,7被下边的设置保护,因此中间只能用4来平铺,同理,3和9之间的6

//因为5没有被保护,因此在整个空间中,用5进行平铺来填充剩余的区域

// testImage2 = [testImage2 resizableImageWithCapInsets:UIEdgeInsetsMake(42, 20, 42, 20) resizingMode:UIImageResizingModeTile];

 

/***********************************************/

//resizableImageWithCapInsets: resizingMode: 方法

//  UIImageResizingModeStretch,  拉伸

//  拉伸的概念是直接按比例将图片放大到与相框尺寸相同的图像,

//testImage2 = [testImage2 resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeStretch];

 

//将上部的三分之一"保护",而后进行显示

//保证原图像上部的三分之一在Y轴上不被拉伸,其他部分按剩余比例拉伸

//testImage2 = [testImage2 resizableImageWithCapInsets:UIEdgeInsetsMake(42, 0, 0, 0) resizingMode:UIImageResizingModeStretch];

 

//将左部的三分之一"保护",而后进行显示

//保证原图像左部的三分之一在Y轴上不被拉伸,其他部分按剩余比例拉伸

//testImage2 = [testImage2 resizableImageWithCapInsets:UIEdgeInsetsMake(0, 20, 0, 0) resizingMode:UIImageResizingModeStretch];

 

//将四周进行保护后

//在X轴上,因为1被左边的设置保护,3被右边的设置保护,因此中间只能用2来拉伸,同理,7和9之间的8

//在Y轴上,因为1被上边的设置保护,7被下边的设置保护,因此中间只能用4来拉伸,同理,3和9之间的6

//因为5没有被保护,因此在整个空间中,用5进行拉伸来填充剩余的区域

//testImage2 = [testImage2 resizableImageWithCapInsets:UIEdgeInsetsMake(42, 20, 42, 20) resizingMode:UIImageResizingModeStretch];

 

//将图片添加到相框

self.imageView2.image = testImage2;

 

//-----imageView3的相关内容----------------------------------------------------------------------------------

 

//读取图片

UIImage *testImage3 = [UIImage imageNamed:@"123456789"];

 

/***********************************************/

//resizableImageWithCapInsets默认是平铺

//resizableImageWithCapInsets默认状况对比图

//testImage3 = [testImage3 resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeTile];

 

/***********************************************/

//resizableImageWithCapInsets: resizingMode: 方法

//  UIImageResizingModeTile,     平铺 (已经测试过了,)

//  UIImageResizingModeStretch,  拉伸

//testImage3 = [testImage3 resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeStretch];

/***********************************************/

 

//将图片添加到相框

self.imageView3.image = testImage3;

// Do any additional setup after loading the view, typically from a nib.

}

 

@end

相关文章
相关标签/搜索