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

相關文章
相關標籤/搜索