IOS UIImage picture stretching skills - resizableImageWithCapInsets

Looking at the mobile market, if a mobile app wants to gain a foothold in the mobile market for a long time, it must at least include the following elements: practical functions, strong user experience, and gorgeous and simple appearance. Behind the gorgeous appearance, the hard work of the artist is indispensable, but if the developers do not know how to display these designed pictures reasonably, these designs will be ruined, and the success will fall short.

For example, the following picture was originally designed as a button background:

 button.png, size: 24x60

Now we use it as a button background, the button size is 150x50:

[java]  view plain copy
  1. // Get the size of the view  
  2. CGSize viewSize = self.view.bounds.size;  
  3.   
  4. // initialize button  
  5. UIButton *button = [[UIButton alloc] init];  
  6. // set size  
  7. button.bounds = CGRectMake(0015050);  
  8. // set position  
  9. button.center = CGPointMake(viewSize.width * 0.5f, viewSize.height * 0.5f);  
  10.   
  11. // load the image  
  12. UIImage *image = [UIImage imageNamed:@"button"];  
  13. // set the background image  
  14. [button setBackgroundImage:image forState:UIControlStateNormal];  
  15.   
  16. // add button  
  17. [self.view addSubview:button];  

Running effect diagram:

As you can see, the effect is very poor. The reason is very simple, because the size of the original image is 24x60, now the entire image is stretched to 150x50 in all directions, and the more serious ones are the four corners of the image.

Some people may immediately think of a solution. You can ask the artist to make the picture bigger. It doesn’t matter how you stretch it. Yes, this is a solution, but not recommended. The reason is simple: 1. The large size of the picture leads to a large installation package, which is also large when loaded into memory; 2. There is a better solution.

Take a closer look at the picture, in fact, the picture will become ugly, it is entirely because the 4 corners are stretched, and the stretch in the middle does not obviously uglify the appearance. Therefore, if the small picture is stretched, it will not become ugly. When the picture is stretched, we only need to stretch the middle rectangular area of ​​the picture, and do not stretch the edge part.

For example, only the rectangular area in the figure below is stretched, and the top, bottom, left, and right edges are not stretched:

iOS provides a very useful API to help us achieve the above functions. Until iOS 6.0, iOS has provided 3 solutions for image stretching, and these solutions will be introduced in detail below.

1. Before iOS 5.0

There is a concept called end cap in iOS, which is used to specify which part of the image does not need to be stretched. For example, in the figure below, black represents the rectangular area that needs to be stretched, and the edges that do not need to be stretched up, down, left, and right are called end caps.

Using this method of UIImage, you can return a stretched UIImage object by setting the end cap width

[java]  view plain copy
  1. - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;  

这个方法只有2个参数,leftCapWidth代表左端盖宽度,topCapHeight代表顶端盖高度。系统会自动计算出右端盖宽度(rightCapWidth)和底端盖高度(bottomCapHeight),算法如下:

[java]  view plain copy
  1. // width为图片宽度  
  2. rightCapWidth = width - leftCapWidth - 1;  
  3.   
  4. // height为图片高度  
  5. bottomCapHeight = height - topCapHeight - 1  

经过计算,你会发现中间的可拉伸区域只有1x1

[java]  view plain copy
  1. // stretchWidth为中间可拉伸区域的宽度  
  2. stretchWidth = width - leftCapWidth - rightCapWidth = 1;  
  3.       
  4. // stretchHeight为中间可拉伸区域的高度  
  5. stretchHeight = height - topCapHeight - bottomCapHeight = 1;  

因此,使用这个方法只会拉伸图片中间1x1的区域,并不会影响到边缘和角落。

下面演示下方法的使用:

[java]  view plain copy
  1. // 左端盖宽度  
  2. NSInteger leftCapWidth = image.size.width * 0.5f;  
  3. // 顶端盖高度  
  4. NSInteger topCapHeight = image.size.height * 0.5f;  
  5. // 重新赋值  
  6. image = [image stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];  

调用这个方法后,原来的image并不会发生改变,会产生一个新的经过拉伸的UIImage,所以第6行中需要将返回值赋值回给image变

运行效果:

可以发现,图片非常美观地显示出来了

注意:

1.这个方法在iOS 5.0出来后就过期了

2.这个方法只能拉伸1x1的区域

 

二、iOS 5.0

在iOS 5.0中,UIImage又有一个新方法可以处理图片的拉伸问题

[java]  view plain copy
  1. - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets  

这个方法只接收一个UIEdgeInsets类型的参数,可以通过设置UIEdgeInsets的left、right、top、bottom来分别指定左端盖宽度、右端盖宽度、顶端盖高度、底端盖高度

[java]  view plain copy
  1. CGFloat top = 25// 顶端盖高度  
  2. CGFloat bottom = 25 ; // 底端盖高度  
  3. CGFloat left = 10// 左端盖宽度  
  4. CGFloat right = 10// 右端盖宽度  
  5. UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);  
  6. // 伸缩后重新赋值  
  7. image = [image resizableImageWithCapInsets:insets];  

运行效果:

 

三、iOS 6.0

在iOS6.0中,UIImage又提供了一个方法处理图片拉伸

[java]  view plain copy
  1. - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode  

对比iOS5.0中的方法,只多了一个UIImageResizingMode参数,用来指定拉伸的模式:

  • UIImageResizingModeStretch:拉伸模式,通过拉伸UIEdgeInsets指定的矩形区域来填充图片
  • UIImageResizingModeTile:平铺模式,通过重复显示UIEdgeInsets指定的矩形区域来填充图片

[java]  view plain copy
  1. CGFloat top = 25// 顶端盖高度  
  2. CGFloat bottom = 25 ; // 底端盖高度  
  3. CGFloat left = 10// 左端盖宽度  
  4. CGFloat right = 10// 右端盖宽度  
  5. UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);  
  6. // 指定为拉伸模式,伸缩后重新赋值  
  7. image = [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];  

running result:


The article is reproduced from Mr. MJ's blog: http://blog.csdn.net/q199109106q/article/details/8615661

Guess you like

Origin blog.csdn.net/qq_32796151/article/details/51698966