原文出處: martin_wjl(@martin_wjl) git
對於圖片拉伸是移動開發中很常見的需求,在前一陣子作項目中須要作一個相似於QQ
聊天氣泡,這個氣泡會根據文字的多少而變化,當時有了三種方案:github
重寫drawRect
方法,使用貝賽爾曲線畫一個氣泡編程
用一個大圖做爲背景,管它怎麼拉伸,確定不會變形json
使用圖片,同時使用系統提供的API
對圖片進行局部拉伸架構
來分析一下這三種作法利弊:性能
第一種:勞民傷財,drawRect
的使用帶來離屏渲染,若是滑動聊天界面將使內存急劇增長,同時我也不會使用貝賽爾曲線,嗚嗚!測試
第二種:大圖的話,顯然所佔空間會比較大,這樣致使最後的安裝包較大,尺寸不合適的圖片加載也會對性能有所影響網站
第三種:顯然這是一種划算的作法,對於怎麼進行局部拉伸也是這篇博客的重點ui
至於 iOS 5 之類的方法,這裏就再也不談了。在 iOS 6 的時候,系統爲咱們提供了這樣一個方法spa
1 |
public func resizableImageWithCapInsets(capInsets: UIEdgeInsets, resizingMode: UIImageResizingMode) -> UIImage |
對於拉伸的方式,有如下兩種:
IUIImageResizingModeStretch
:拉伸模式,經過拉伸UIEdgeInsets
指定的矩形區域是咱們要保護的區域,也就是不被拉伸的區域
UIImageResizingModeTile
:平鋪模式,經過重複顯示UIEdgeInsets
指定的矩形區域是要保護的區域,也就是不被重複顯示的區域
來作四個測試,假如咱們的原始圖像尺寸爲60*128
當咱們設置capInsets
爲如下四種值的時候有什麼樣子的效果:
1:capInsets
參數爲UIEdgeInsetsMake(0, 0, 0, 0)
2:capInsets
參數爲UIEdgeInsetsMake(42, 0, 0, 0)
3:capInsets
參數爲UIEdgeInsetsMake(0, 20, 0, 0)
4:capInsets
參數爲UIEdgeInsetsMake(42, 20, 42, 20)
在一個180*384
的窗口進行測試圖像,對於實踐的結果,能夠在這個地址中看到。
四種測試結果是:
1: 原始圖像拉伸,比例放大
2: 咱們對圖片上面的區域進行了保護,其餘區域進行了拉伸,保護區域在Y軸保持了原比例,可是X軸方向進行了拉伸
3: 咱們對圖片的左側區域進行了保護,其餘區域進行了拉伸,保護區域在X軸保持了原比例,可是在Y軸方向進行了拉伸
4: 咱們對除了中心區域的位置進行了保護,中心區域進行了拉伸,四個角進行了雙層保護,其他被保護區域在X、Y軸的拉伸與第二、3種狀況下相同,效果圖以下:
效果圖4
與上面的場景相同,只不過再也不拉伸,改成平鋪的方式,來嘗試如下四種狀況:
1:capInsets
參數爲UIEdgeInsetsMake(0, 0, 0, 0)
2:capInsets
參數爲UIEdgeInsetsMake(42, 0, 0, 0)
3:capInsets
參數爲UIEdgeInsetsMake(0, 20, 0, 0)
4:capInsets
參數爲UIEdgeInsetsMake(42, 20, 42, 20)
在一個180*384
的窗口進行測試圖像,對於實踐的結果,能夠在這個地址中看到。
結論就是:
1: 按比例平鋪
2: 咱們對圖片上面的區域進行了保護,其餘區域按比例平鋪,保護區域在Y軸保持了原比例,可是X軸方向進行了平鋪填充
3: 咱們對圖片的左側區域進行了保護,其餘區域按比例平鋪,保護區域在X軸保持了原比例,可是在Y軸方向進行了平鋪填充
4: 咱們對除了中心區域的位置進行了保護,中心區域按比例平鋪,四個角進行了雙層保護,其他被保護區域在X、Y軸的平鋪與第二、3種狀況下相同,效果圖以下:
效果5
注: 以上的代碼測試來自SketchK七爺
何爲Image Slicing
呢?,其實就至關於一個可視化的resizableImageWithCapInsets
,能夠用於指定在圖片縮放時用來填充的像素。咱們能夠在Xcode
的Assets.xcassets
目錄中選擇要slicing
的圖片,點擊圖片界面右下方的Show Slicing
按鈕,在想要設定切片的圖片上點擊Start Slicing
,將出現左中右(或者上中下)三條能夠拖動的指示線,經過拖動它們來設定實際的縮放範圍。
圖
咱們剛纔說,他就是可視化的resizableImageWithCapInsets
,那麼它的capInsets
在哪裏呢?打開圖片對應的.json
文件,代碼以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "images" : [ { "resizing" : { "mode" : "9-part", "center" : { "mode" : "tile", "width" : 42, "height" : 92 }, "cap-insets" : { "bottom" : 0, "top" : 95, "right" : 41, "left" : 0 } }, |
從文件能夠看出來top
、left
、bottom
、right
對應的就是上左下右的指示線,看到mode
爲tile
,就知道Image Slicing
默認爲平鋪縮放,對於width
與Height
是作什麼的呢?Width
表明的是左側線(或者上方線)和中間線之間的區域,Height
表明的是上側線和中間線之間的區域。
看一下剛纔圖片運行起來的效果
測試結果
很神奇呀!灰色區域都會被隱藏,咱們發現灰色區域位於右側線與中間線或者下方線與中間線之間。來分析一下各個數字的平鋪:
3位與右側線的右側,不會發生變化
1位與左側線與中間線之間,Y軸保持比例不變,X軸平鋪
6位與右側線的右側,可是也位與上方線與中間線之間,因此會保持X軸不變,Y軸平鋪
4位與左側線與中間線之間,同時也位與上方線與中間線之間,會填充其餘全部的空餘區域。
好繞啊!仍是可視化比較簡單,只要手動調試一下,就能夠比較直觀的看到效果,但願能夠幫到你,Demo能夠進行下載。
問啊-定製化IT教育平臺,牛人一對一服務,有問必答,開發編程社交頭條 官方網站:www.wenaaa.com
QQ羣290551701 彙集不少互聯網精英,技術總監,架構師,項目經理!開源技術研究,歡迎業內人士,大牛及新手有志於從事IT行業人員進入!