在iOS開發中如何優雅地進行圖片縮放?

原文出處: 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 可視化縮放

何爲Image Slicing呢?,其實就至關於一個可視化的resizableImageWithCapInsets,能夠用於指定在圖片縮放時用來填充的像素。咱們能夠在XcodeAssets.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

        }

      },

從文件能夠看出來topleftbottomright對應的就是上左下右的指示線,看到modetile,就知道Image Slicing默認爲平鋪縮放,對於widthHeight是作什麼的呢?Width表明的是左側線(或者上方線)和中間線之間的區域,Height表明的是上側線和中間線之間的區域。

看一下剛纔圖片運行起來的效果

 

測試結果

很神奇呀!灰色區域都會被隱藏,咱們發現灰色區域位於右側線與中間線或者下方線與中間線之間。來分析一下各個數字的平鋪:

  • 3位與右側線的右側,不會發生變化

  • 1位與左側線與中間線之間,Y軸保持比例不變,X軸平鋪

  • 6位與右側線的右側,可是也位與上方線與中間線之間,因此會保持X軸不變,Y軸平鋪

  • 4位與左側線與中間線之間,同時也位與上方線與中間線之間,會填充其餘全部的空餘區域。

好繞啊!仍是可視化比較簡單,只要手動調試一下,就能夠比較直觀的看到效果,但願能夠幫到你,Demo能夠進行下載。

問啊-定製化IT教育平臺,牛人一對一服務,有問必答,開發編程社交頭條 官方網站:www.wenaaa.com

QQ羣290551701 彙集不少互聯網精英,技術總監,架構師,項目經理!開源技術研究,歡迎業內人士,大牛及新手有志於從事IT行業人員進入!

相關文章
相關標籤/搜索