前面我們介紹了關(guān)于UIImage的知識(shí)點(diǎn),相信大家對(duì)他有了了解,這里繼續(xù)為大家講解
UIkit框架
中的
UIImage
。
圖片拉伸
當(dāng)我們的圖片比所要填充的區(qū)域小時(shí),會(huì)導(dǎo)致圖片變形。如以下圖片,原始大小為
100*30
,將其放到一個(gè)
300*50
的
UIImageView
中時(shí),整個(gè)圖片被拉伸。
原始圖片
拉伸后的圖片
這時(shí)我們就需要做特殊的處理。
Android
的同學(xué)應(yīng)該都知道
.9
圖,這種圖片可以只拉伸中間的部分,而保持四個(gè)角不變形。在
iOS
中也支持這種操作。在早期的
iOS
版本中,
UIImage
提供了如下方法來(lái)執(zhí)行此操作:
func stretchableImageWithLeftCapWidth(_ leftCapWidth: Int, topCapHeight topCapHeight: Int) -> UIImage
這個(gè)方法通過(guò)
leftCapWidth
和
topCapHeight
兩個(gè)參數(shù)來(lái)定義四個(gè)角的大小。不過(guò)這個(gè)方法在
iOS 5
中就被
Deprecated
了,對(duì)應(yīng)的兩個(gè)屬性
leftCapWidth
和
topCapHeight
也是相同的命運(yùn)。所以現(xiàn)在不建議使用它們。另外,對(duì)于如何解釋
leftCapWidth
和
topCapHeight
,大家可以參考一下
@M了個(gè)J的
iOS圖片拉伸技巧。
在
iOS 5
中,我們可以使用以下方法來(lái)執(zhí)行相同的操作:
func resizableImageWithCapInsets(_ capInsets: UIEdgeInsets) -> UIImage
這個(gè)方法通過(guò)一個(gè)
UIEdgeInsets
來(lái)指定上下左右不變形的寬度或高度。它會(huì)返回一個(gè)新的圖像。而如果圖像被拉伸,則會(huì)以平鋪的方式來(lái)處理中間的拉伸區(qū)域。
我們對(duì)上面的圖片做如下處理:
let resizedButtonImageView = UIImageView(image: normalButtonImage?.resizableImageWithCapInsets(UIEdgeInsets(top: 15, left: 15, bottom: 15, right: 15)))
resizedButtonImageView.frame = CGRectMake(0, 60, 300, 50)
其得到的結(jié)果如下所示:
在
iOS 6
,
Apple
又為我們提供了一個(gè)新的方法,相較于上面這個(gè)方法,只是多一個(gè)
resizingMode
參數(shù),允許我們指定拉伸模式。
func resizableImageWithCapInsets(_ capInsets: UIEdgeInsets, resizingMode resizingMode: UIImageResizingMode) -> UIImage
這個(gè)方法的拉伸模式分兩種:平鋪
(Tile)
和拉伸
(Stretch)
。如果是平鋪模式,則跟前一個(gè)方法是一樣的效果。
動(dòng)效圖片對(duì)象
如果我們有一組大小和縮放因子相同的圖片,就可以將這些圖片加載到同一個(gè)
UIImage
對(duì)象中,形成一個(gè)動(dòng)態(tài)的
UIImage
對(duì)象。為此,
UIImage
提供了以下方法:
class func animatedImageNamed(_ name: String, duration duration: NSTimeInterval) -> UIImage?
這個(gè)方**加載以
name
為基準(zhǔn)文件名的一系列文件。如,假設(shè)我們的
name
參數(shù)值為
”swift”
,則這個(gè)方**加載諸如
”swift0”, “swift1”,…, “swift1024”
這樣的一系列的文件。
這里有兩個(gè)問(wèn)題需要注意:
文件的序號(hào)必須是從
0
開(kāi)始的連續(xù)數(shù)字,如果不從
0
開(kāi)始,則在
Playground
中是會(huì)報(bào)錯(cuò)的。而如果中間序號(hào)有斷,而中斷后的圖片是不會(huì)被加載的。
所有文件的大小和縮放因子應(yīng)該是相同的,否則顯示時(shí)會(huì)有不可預(yù)期的結(jié)果,這種結(jié)果主要表現(xiàn)為播放的順序可能是雜亂的。
如果我們有一組基準(zhǔn)文件名不同的文件,但其大小和縮放因子相同,則可能使用以下方法:
class func animatedImageWithImages(_ images: [UIImage], duration duration: NSTimeInterval) -> UIImage?
傳入一個(gè)
UIImage
數(shù)組來(lái)拼裝一個(gè)動(dòng)效
UIImage
對(duì)象。
另外,
UIImage
也提供了
resizable
版本的動(dòng)效方法,如下所示:
class func animatedResizableImageNamed(_ name: String, capInsets capInsets: UIEdgeInsets, duration duration: NSTimeInterval) -> UIImage?
class func animatedResizableImageNamed(_ name: String, capInsets capInsets: UIEdgeInsets, resizingMode resizingMode: UIImageResizingMode, duration duration: NSTimeInterval) -> UIImage?
第一個(gè)方法的
UIImageResizingMode
默認(rèn)是
UIImageResizingModeTile
,所以如果想對(duì)圖片做拉伸處理,可以使用第二個(gè)的方法,并傳入
UIImageResizingModeStretch
。
圖片大小的限制
UIImage
對(duì)象使用的圖片大小盡量小于
1024*1024
。因?yàn)檫@么大的圖片消耗的內(nèi)存過(guò)大,在將其作為
OpenGL
中的貼圖或者是繪制到
view/layer
中時(shí),可以會(huì)出現(xiàn)問(wèn)題。如果僅僅是代碼層面的操作的話,則沒(méi)有這個(gè)限制。比如,將一個(gè)大于
1024*1024
的圖片繪制到位圖圖形上下文中以重新設(shè)定其大小。事實(shí)上,我們需要通過(guò)這種操作來(lái)改變圖片大小,以將其繪制到視圖中。
支持的圖片格式
需要注意的一點(diǎn)是
RGB-565
格式的
BMP
文件在加載時(shí)會(huì)被轉(zhuǎn)換成
ARGB-1555
格式。
原文來(lái)自:南峰子的技術(shù)博客