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
what, Android is so tall? In fact, iOS also provides similar functions after version 5.0, UIImage's
Method, after iOS6.0, an enhanced version has been added
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:
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: