Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stretching an UIImage while preserving the corners

I'm trying to stretch a navigation arrow image while preserving the edges so that the middle stretches and the ends are fixed.

Here is the image that I'm trying to stretch:

enter image description here

The following iOS 5 code allows the image when resized to stretch the center portions of the image defined by the UIEdgeInsets.

[[UIImage imageNamed:@"arrow.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 7, 15, 15)];

This results in an image that looks like this (if the image's frame is set to 70 pixels wide):

enter image description here

This is actually what I want but resizableImageWithCapInsets is only supported on iOS 5 and later.

Prior to iOS 5 the only similar method is stretchableImageWithLeftCapWidth:topCapHeight but you can only specify the top and left insets which means the image has to have equal shaped edges.

Is there an iOS 4 way of resizing the image the same as iOS 5's resizableImageWithCapInsets method, or another way of doing this?

like image 835
Camsoft Avatar asked Jan 16 '12 12:01

Camsoft


3 Answers

Your assumption here is wrong:

Prior to iOS 5 the only similar method is stretchableImageWithLeftCapWidth:topCapHeight but you can only specify the top and left insets which means the image has to have equal shaped edges.

The caps are figured out as follows - I'll step through the left cap, but the same principle applies to the top cap.

Say your image is 20px wide.

  • Left cap width - this is the part on the left hand side of the image that cannot be stretched. In the stretchableImage method you send a value of 10 for this.
  • Stretchable part - this is assumed to be one pixel in width, so it will be the pixels in column "11", for want of a better description
  • This means there is an implied right cap of the remaining 9px of your image - this will also not be distorted.

This is taken from the documentation

leftCapWidth

End caps specify the portion of an image that should not be resized when an image is stretched. This technique is used to implement buttons and other resizable image-based interface elements. When a button with end caps is resized, the resizing occurs only in the middle of the button, in the region between the end caps. The end caps themselves keep their original size and appearance.

This property specifies the size of the left end cap. The middle (stretchable) portion is assumed to be 1 pixel wide. The right end cap is therefore computed by adding the size of the left end cap and the middle portion together and then subtracting that value from the width of the image:

rightCapWidth = image.size.width - (image.leftCapWidth + 1);

like image 144
jrturton Avatar answered Sep 22 '22 14:09

jrturton


UIImage *image = [UIImage imageNamed:@"img_loginButton.png"];
    UIEdgeInsets edgeInsets;
    edgeInsets.left = 0.0f;
    edgeInsets.top = 0.0f;
    edgeInsets.right = 5.0f; //Assume 5px will be the constant portion in your image
    edgeInsets.bottom = 0.0f;
    image = [image resizableImageWithCapInsets:edgeInsets];
//Use this image as your controls image
like image 44
Vicky Avatar answered Sep 22 '22 14:09

Vicky


Your example is perfectly possible using stretchableImageWithLeftCapWidth:topCapHeight: with a left cap of 15 (apparently, from reading your code). That will horizontally stretch the button by repeating the middle column.

like image 26
Steven Kramer Avatar answered Sep 23 '22 14:09

Steven Kramer