天天看點

IOS中圖檔(UIImage)拉伸技巧

簡單暴力,卻是最最常用的方法,直接将圖檔設定為imageview的image屬性,圖檔便會随uiimageview對象的大小做自動拉伸。這種拉伸的方法有一個緻命的缺陷,它會使圖像發生失真與形變。

- (uiimage *)stretchableimagewithleftcapwidth:(nsinteger)leftcapwidth topcapheight:(nsinteger)topcapheight;

這個函數我們可以用來拉伸類似qq,微信的聊天氣泡背景圖,它的兩個參數分别leftcapwidth和topcapheight,這兩個參數給定一個坐标,比如:

<a href="http://my.oschina.net/u/2340880/blog/403996#">?</a>

1

2

<code>    </code><code>uiimage * img= [uiimage imagenamed:@</code><code>"11.png"</code><code>];</code>

<code>    </code><code>img = [img stretchableimagewithleftcapwidth:1 topcapheight:1];</code>

這段代碼的意思是将圖檔從左起第2列,上起第2行,坐标為(2,2)的像素點進行複制。将圖檔進行拉伸。這個方法和上面的方法比起來似乎靈活性更多了,但其也有它的一些局限,如果被拉伸的圖檔中間也有需要拉伸的像素,這個方法就無能為力了,例如,如下的一張圖檔,我們需要将其拉伸放大:

IOS中圖檔(UIImage)拉伸技巧

便會出現這樣的效果:

IOS中圖檔(UIImage)拉伸技巧

這明顯和我們的意圖是不符的,那麼,我們可以使用下面的方法。

- (uiimage *)resizableimagewithcapinsets:(uiedgeinsets)capinsets;

這個函數需要設定一個uiedgeinsets參數,uiedgeinsets結構體如下:

3

<code>typedef</code> <code>struct</code> <code>uiedgeinsets {</code>

<code>    </code><code>cgfloat top, left, bottom, right; </code>

<code>} uiedgeinsets;</code>

它分别對用了圖檔進行拉伸的區域距離頂部、左部、下部、右部的像素。比如,一個10*10像素的圖檔,将uiedgeinsets參數全部設定為1,則實際拉伸的部分就是中間的8*8的區域的像素。有一點需要注意,這個方法預設使用的拉伸模式是區域複制,比如還是上面的圖案,如下代碼拉伸:

<code>    </code><code>img = [img resizableimagewithcapinsets:uiedgeinsetsmake(1, 1, 1, 1)];</code>

結果如下:

IOS中圖檔(UIImage)拉伸技巧

可以明顯的看到中間的虛線,這便是區域複制的傑作。

那麼問題又來了,如果某些圖檔中間有漸變,我們該怎麼處理了,來看下一個函數。

- (uiimage *)resizableimagewithcapinsets:(uiedgeinsets)capinsets resizingmode:(uiimageresizingmode)resizingmode;

這個函數和上一個函數相比,唯一的差别是多了一個參數。這個參數是個枚舉,如下:

4

<code>typedef</code> <code>ns_enum(nsinteger, uiimageresizingmode) {</code>

<code>    </code><code>uiimageresizingmodetile,</code><code>//進行區域複制模式拉伸</code>

<code>    </code><code>uiimageresizingmodestretch,</code><code>//進行漸變複制模式拉伸</code>

<code>};</code>

現在就明了了,我們隻需要設定一下模式,就可以實作漸變拉伸了:

<code>    </code><code>img = [img resizableimagewithcapinsets:uiedgeinsetsmake(1, 1, 1, 1) resizingmode:uiimageresizingmodestretch];</code>

來看一下效果:

IOS中圖檔(UIImage)拉伸技巧

圓角按鈕,空心按鈕,漸變的背景,内容可變的标簽,聊天氣泡等等這樣的素材在app中很可能會多次出現,并且每次出現的尺寸可能還會略微有些差異,如果僅僅依靠美工的素材,恐怕不僅很難達到要求,也會額外增加軟體的記憶體開銷,這時,我們使用恰當的拉伸技巧,能使我們的代碼更加健壯,app更加高效。

你是否注意觀察過最細的線?

看到上面的問句,你可能有些差異。最細的線不就是一像素麼?确實,能繪圖畫出來的最細的實心線确實是一像素,但在一個項目中,我們優秀的美工察覺到無論她把線做的多麼細,無論我怎樣控制拉伸方法,繪制出的登入框總是沒有qq的細,qq的框線看起來更加幹脆利索。後來索性用繪圖畫出登入框,結果很不幸,我依然無法将線做到像qq登入框那樣細緻。後來偶然試了一種方法,不知原理是否正确,效果總算達到了,當然這也要歸功于我們的美工,她将一個圖檔做的很大,适配最大的分辨率,然後讓我手動縮,如此一來,那線就變得非常細。

繼續閱讀