UIImage缩放

标签(空格分隔): UI设计


普通拉伸图片

带边框的图片如果实用常规的缩放,边框部分会按照缩放比例拉伸或者压缩,会导致图片变形。 例如下面这样:

我们有这样一张图片:

.

我们将一个button的背景设置为这张图片,代码如下:

1
2
3
4
5
6
7
self.view.backgroundColor = [UIColor whiteColor];

_purpleButton= [[UIButton alloc]initWithFrame:CGRectMake(50, 130, 200, 100)];
[_purpleButton setTitle:@"Test Button" forState:UIControlStateNormal];
UIImage *buttonImage = [UIImage imageNamed:@"purple_button@2x.png"];
[_purpleButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
[self.view addSubview:_purpleButton];

图片的大小比button的frame小,会自动将图片进行拉伸,拉伸的效果如下:

.

resizableImageWithCapInsets

显然这并不是我们想要的效果。 左右边框由于按钮frame过大被过度拉伸。 iOS中有一个方法提供给开发者使用。叫做resizableImageWithCapInsets::以某一偏移值为偏移的可伸缩图像(保证偏移值内的图像不被拉伸或者压缩)

用法描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
resizableImageWithCapInsets:  
Creates and returns a new image object with the specified cap insets.
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets
Parameters
capInsets
The values to use for the cap insets.
Return Value
A new image object with the specified cap insets.
Discussion
You use this method to add cap insets to an image or to change the existing cap insets of an image. In both cases, you get back a new image and the original image remains untouched.

During scaling or resizing of the image, areas covered by a cap are not scaled or resized. Instead, the pixel area not covered by th

输入参数为:

1
2
3
4
//Defines inset distances for views.
typedef struct {
CGFloat top, left, bottom, right;
} UIEdgeInsets;

分别表示上下左右四个方向的偏移量。表示拉伸图片的时候上下左右需要忽略的像素大小。

我们首先将UIEdgeInsets设置为UIEdgeInsetsMake(0, 0, 0, 0),然后拉伸图片看看效果。

再viewDidLoad方法中加入下面代码:


self.view.backgroundColor = [UIColor whiteColor];
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(50, 130, 200, 100)];
[button setTitle:@"Test Button" forState:UIControlStateNormal];
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(0,0, 0, 0);
UIImage *backGroundImage = [[UIImage imageNamed:@"purple_button@2x.png" ]resizableImageWithCapInsets:edgeInsets];
[button setBackgroundImage:backGroundImage forState:UIControlStateNormal];

[self.view addSubview:button];

效果如下所示:

因为我们上面把上下左右需要忽略的像素值设置为0,所以整个图片都被一个一个的复制。直到达到button的frame大小。

垂直拉伸图片

如果我们想单纯的垂直拉伸图片,需要忽略左边和右边的边缘,如下所示:

现在忽略了左边和右边的边缘,然后再拉伸的话,中间的区域就会被不断的复制。需要忽略左边和右边各8个像素。将UIEdgeInsets 设置为UIEdgeInsetsMake(0, 8, 0, 8)

代码如下:


self.view.backgroundColor = [UIColor whiteColor];
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(50, 130, 200, 100)];
[button setTitle:@"Test Button" forState:UIControlStateNormal];
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(0,8, 0, 8);
UIImage *backGroundImage = [[UIImage imageNamed:@"purple_button@2x.png" ]resizableImageWithCapInsets:edgeInsets];
[button setBackgroundImage:backGroundImage forState:UIControlStateNormal];

[self.view addSubview:button];

效果图如下:

这样拉伸的效果就看起来好了很多。

水平拉伸图片

忽略上部和下部的各8个像素的边缘位置,然后中间区域的部分再拉伸的时候就会被一直复制。

代码:


self.view.backgroundColor = [UIColor whiteColor];
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(50, 130, 200, 100)];
[button setTitle:@"Test Button" forState:UIControlStateNormal];
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(8,0, 8, 0);
UIImage *backGroundImage = [[UIImage imageNamed:@"purple_button@2x.png" ]resizableImageWithCapInsets:edgeInsets];
[button setBackgroundImage:backGroundImage forState:UIControlStateNormal];

[self.view addSubview:button];

效果图:

最佳使用方式

由于该图片边框四周都是不均匀的,我们需要再上下左右都忽略一定的像素大小再进行拉伸,才可以达到想要的效果,这样我们上下左右都忽略8个像素的大小进行尝试,将UIEdgeInsets的大小设置为UIEdgeInsetsMake(8, 8, 8, 8):

代码:


self.view.backgroundColor = [UIColor whiteColor];
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(50, 130, 200, 100)];
[button setTitle:@"Test Button" forState:UIControlStateNormal];
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(8,8, 8, 8);
UIImage *backGroundImage = [[UIImage imageNamed:@"purple_button@2x.png" ]resizableImageWithCapInsets:edgeInsets];
[button setBackgroundImage:backGroundImage forState:UIControlStateNormal];

[self.view addSubview:button];

效果图:

这才是我们想要的效果。当图片大小和要使用图片的view的frame不一致的时候,拉伸的时候就可以忽略掉边缘,然后进行拉伸。这样效果会比较好,边缘的大小值还需要自己根据图片自己设定。