導(dǎo)語(yǔ):
有時(shí)候?qū)σ粋€(gè)圖片進(jìn)行常規(guī)的縮放達(dá)不到我們想要的效果西雀,比如聊天氣泡的大小、帶邊框的按鈕背景。通常我們會(huì)設(shè)置某個(gè)偏移值對(duì)圖片進(jìn)行拉伸來(lái)實(shí)現(xiàn)我們想要的效果。iOS6以后有兩條相似的API可以解決這一問(wèn)題松邪,下文簡(jiǎn)稱帶模式的縮放和不帶模式的縮放。
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets;
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode;
下面是官方文檔對(duì)API的解釋:
Each inset defines the potion of the image that does not stretch in the given dimension. The regions inside an image’s top and bottom insets maintain a fixed height, and the areas inside the left and right insets maintain a fixed width. Figure 2 shows how each part of a nine-part image stretches as the image itself is stretched to fill the available space. The corners of the image do not change size because they are inside both a horizontal and vertical inset.
也就是說(shuō)會(huì)傳入一個(gè)UIEdgeInsets
類型的結(jié)構(gòu)體將UIImage
分為9個(gè)(也有可能是2個(gè))部分哨查,并對(duì)其中間部分和四個(gè)邊進(jìn)行縮放逗抑,但是四個(gè)角會(huì)保持不變。
下面分別介紹這兩條API寒亥。
不帶模式的縮放
縮放模式有兩種邮府,分別是UIImageResizingModeTile
平鋪和UIImageResizingModeStretch
拉伸。如果不指定縮放模式护盈,則會(huì)根據(jù)傳入UIEdgeInsets
類型的結(jié)構(gòu)體的不同而進(jìn)行不同的縮放挟纱。
原文是這么說(shuō)的:
iOS uses different rendering techniques, with different performance characteristics, depending on the size of each resizable area in the image:
If resizable areas have a width or height of 1 pixel—that is, a horizontally resizable area is 1 pixel wide, a vertically resizable area is 1 pixel tall, or the center region of the image is 1 x 1 pixel—iOS draws the image by stretching the 1-pixel region. This mode provides the fastest performance (for nonzero cap insets).
If resizable areas have a width or height greater than 1 pixel, iOS draws the image by tiling the region. This mode provides reduced performance, but can be useful for images with textured (rather than solid-color) content in their resizable areas.
If the entire image is resizable—that is, the capInsets parameter is UIEdgeInsetsZero—and its size is greater than 1 x 1 pixel, iOS draws the image by tiling the entire image. This mode is faster than the tiling mode for nonzero cap insets.
也就是說(shuō),
- 如果中間部分邊長(zhǎng)都小于或等于1,這種情況下可變部分從上往下腐宋、從左至右按一個(gè)像素偏移值按照拉伸模式來(lái)放大。若中間部分有一邊大于1檀轨,則大于1的那邊按平鋪模式縮放胸竞,小于1的那邊以一個(gè)像素的默認(rèn)偏移值按拉伸模式縮放。
- 如果中間部分邊長(zhǎng)大于1x1参萄;在這種情況下可變部分按照平鋪模式來(lái)放大卫枝。
- 如果中間部分大小等于圖片的大小,并且圖片大小大于1x1讹挎,也就是說(shuō)傳入的參數(shù)為
UIEdgeInsetsZero
,在這種情況下可變部分按照平鋪模式來(lái)放大校赤。
下面用一張對(duì)稱的圖片來(lái)測(cè)試吆玖,圖片大小是90x90,imageView
大小為180x180马篮,上面是測(cè)試圖下面是原圖沾乘。
中間部分大小為0的情況,傳入的參數(shù)為:UIEdgeInsetsMake(image.size.height*0.5, image.size.width*0.5, image.size.height*0.5, image.size.width*0.5)
中間部分疊加(小于0)的情況浑测,傳入的參數(shù)為:UIEdgeInsetsMake(image.size.height*0.5, image.size.width*0.5, image.size.height*0.5+20, image.size.width*0.5+20)
中間部分邊長(zhǎng)均小于1的情況翅阵,傳入的參數(shù)為:UIEdgeInsetsMake(image.size.height*0.5, image.size.width*0.5, image.size.height*0.5-0.5, image.size.width*0.5-0.5)
中間部分邊長(zhǎng)均大于1的情況,傳入的參數(shù)為:UIEdgeInsetsMake(image.size.height*0.3, image.size.width*0.3, image.size.height*0.3, image.size.width*0.3)
中間部分等于圖片大小的情況迁央,傳入的參數(shù)為:UIEdgeInsetsZero
帶模式的縮放
這種縮放方式出現(xiàn)在iOS6+掷匠,官方說(shuō)明如下:
This method is exactly the same as its counterpart resizableImageWithCapInsets: except that the resizing mode of the new image object can be explicitly declared. You should only call this method in place of its counterpart if you specifically want your image to be resized with the UIImageResizingModeStretch resizing mode.
意思就是這種縮放方式和前面的差不多,除非你一定要用拉伸的方式來(lái)放大圖片岖圈,否則還是建議你使用不帶模式的方式來(lái)處理你的圖片讹语。
拉伸模式,傳入的參數(shù)為:UIEdgeInsetsMake(image.size.height*0.3, image.size.width*0.3, image.size.height*0.3, image.size.width*0.3)
平鋪模式蜂科,傳入的參數(shù)為:UIEdgeInsetsMake(image.size.height*0.3, image.size.width*0.3, image.size.height*0.3, image.size.width*0.3)
這兩種方法都不會(huì)改變?cè)瓐D顽决,而是返回一張新的圖片。其實(shí)在像素為1的情況下也看不出是平鋪模式還是拉伸模式(性能上拉伸模式好得多)崇摄,如果是純色背景兩種模式區(qū)別也不大擎值。anyway,知道總比不知道要強(qiáng)逐抑。