iOS thoroughly understands resizableImageWithCapInsets

Anyone who has done Android screen adaptation should have heard of .9png, which is a picture format that solves the problem of stretching and undistorting pictures under different screens. Using pictures in .9png format, you can specify stretchable and non-stretchable areas, such as buttons with rounded corners, dialog boxes with arrows, etc. You can specify rounded corners or arrows not to stretch, but only to stretch the repeatable " Rectangle" area, for .9png, please refer to

.9png wrote
http://isux.tencent.com/android-ui-9-png.html

 

what, Android is so tall? In fact, iOS also provides similar functions after version 5.0, UIImage's

wrote
resizableImageWithCapInsets

 Method, after iOS6.0, an enhanced version has been added

wrote
resizableImageWithCapInsets:resizingMode:

 The difference is that iOS6 adds a resizingMode to specify whether to use tiling or stretching to process images

 

  • Parameter Description
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets
                            resizingMode:(UIImageResizingMode)resizingMode

 capInsets: Specifies the area that can be stretched

 

resizingMode: Specify the processing mode - stretch or tile

what the hell? do not know? ? Officer, don't worry, listen to me slowly

  • code description



 Suppose I want to keep the rounded corners and arrows in the next dialog image , and then double the width and height of the image
 

 First [Mark man] to look at the various positions of the rounded corners



 

 Knowing the boundaries, let's start coding. Note that the size of the original image is 170X50. Here I set the size of _tileImgView (UIImageView) to a fixed 340X100, in order to view the effect of the enlarged image.

 

UIImage *img = [UIImage imageNamed:@"msg.jpg"];
    UIEdgeInsets tileSets = {.left = 10, .top = 17, .right = 10, .bottom = 10};
    UIImage *tileImage = [img resizableImageWithCapInsets:tileSets resizingMode:UIImageResizingModeTile];
    _tileImgView.image = tileImage;

 

 

 Let's take a look at the effect.

 Well, there is no problem with the rounded corners, but wait, why are there three arrows, and I am instantly confused?

Needless to say, the problem must be tileSets (stretchable area), so what exactly is a stretchable area?



 Is it the shaded rectangular area shown above? No, absolutely not, because if so, we

The picture processing will be perfect, there will be no three arrows. So what is it? In fact, refer to Android's

.9png, divided into two parts, a horizontal stretch area and a vertical area.

Vertical area = [top,bottom]

Horizontal area=[left,right]

Specifically as shown in the figure below

Horizontal area: When you need to stretch the image in the X direction, you need to use the area between [left, right] to fill the area that needs to be stretched, left means

The distance from the left border, right indicates the distance from the right border, the area between these two lines is used to fill the extra area that needs to be stretched



 
 
 Vertical filling area: When you need to stretch the image in the Y direction, you need to use the area between [top, bottom] to fill the area to be stretched, top represents the distance from the upper boundary, bottom represents the distance from the lower boundary. The area between the two lines is used to fill in the extra area that needs to be stretched



 

So when we change from 50 to 100 vertically, because the stretched area is a rectangular strip as shown in the picture above, the vertical performance is perfect.

 

Let's analyze the horizontal area: the size of the stretchable area is 170-10(left)-10(right)=150, and the non-stretchable area is a 10-pixel rounded corner on the left border and a 10-pixel rounded corner on the right border.

The resizableImageWithCapInsets of iOS will handle the stretching of pictures as follows: keep the non-stretchable area at both ends, and fill the stretchable area in the middle that needs to be stretched



 Retain 10 pixels on the left and right, and use the stretchable area to fill the remaining 320 pixels in the middle. Because we use the tiling method, the middle will use 170 (original image size)-10 (left)-10 ( right)=150 stretchable area to fill the remaining 320 pixels

 so the final effect is 150+150+20=320, exactly three arrows appear



 

The above is just a schematic diagram, please ignore the original scale.

 

What if we change tileSets to the following form?

UIImage *img = [UIImage imageNamed:@"msg.jpg"];
    UIEdgeInsets tileSets = {.left = 20, .top = 17, .right = 140, .bottom = 10};
    UIImage *tileImage = [img resizableImageWithCapInsets:tileSets resizingMode:UIImageResizingModeTile];
    _tileImgView.image = tileImage;

 

 Our stretchable area is only 10 pixels (170-20-140), which is just the width of the arrow; the area that needs to be stretched has 180 (340-20-140),

In this way, the result of our program running should be 180/10=18, which contains 18 arrow effects



 After knowing the principle, go back to the question at the beginning, what if you keep the rounded corners and an arrow? As long as the arrow is not in the stretchable area

 

code show as below

 

 

UIImage *img = [UIImage imageNamed:@"msg.jpg"];
    UIEdgeInsets tileSets = {.left = 40, .top = 17, .right = 77, .bottom = 10};
    UIImage *tileImage = [img resizableImageWithCapInsets:tileSets resizingMode:UIImageResizingModeTile];
    _tileImgView.image = tileImage;

 
 Let's see the effect



 Perfect, but wait, it looks like the following code can be used to achieve the same effect:

UIEdgeInsets tileSets = {.left = 40, .top = 17, .right = 77, .bottom = 10};
    UIEdgeInsets tileSets = {.left = 40, .top = 17, .right = 129, .bottom = 10};
    UIEdgeInsets tileSets = {.left = 32, .top = 17, .right = 10, .bottom = 10};

 What to do, what to do? Don't panic, check out Apple's documentation:

Apple's documentation says
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).

 It probably means that if UIImageResizingModeStretch (stretching mode) is used , it is best to save a pixel length or width in the stretched area, so that the performance is optimal. As for tiling mode, there is no description.

 

Finally, friends who want to know let me know, in UIImageResizingModeTile ( tiling mode), how big is the best stretch area definition? Isn't one pixel the best performance?

 

The source code is as follows:

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327001754&siteId=291194637