I know this topic has lots of Q&A, I read them all and still couldn't get it going... I'm trying to stretch an image, while keeping its rounded edges.
This is my image (104x77px):
this is the code I'm using:
UIImage *bg = [UIImage imageNamed:@"btnBg"];
UIEdgeInsets insets = UIEdgeInsetsMake((bg.size.height - 1)/2, (bg.size.width - 1)/2, (bg.size.height - 1)/2, (bg.size.width - 1)/2);
bg = [bg resizableImageWithCapInsets:insets];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 50, 44)];
imgView.image = bg;
UIImageView *imgView2 = [[UIImageView alloc] initWithFrame:CGRectMake(20, 70, 250, 44)];
imgView2.image = bg;
[self.view addSubview:imgView];
[self.view addSubview:imgView2];
and this is the problem:
As you can see each image has different edges. What am I doing wrong?!
Whenever any scaling is involved, images of two different dimensions can't look quite the same. However you can break your image into three parts: the left corners, the middle section (just the parallel lines), and the right corners.
Now to create image views of different sizes, you'll keep the left and right parts constant, and scale the middle section, which won't look distorted as long as you keep the heights constant.
Note that I have give the height of fitInRect
as 77 because that's the original image height. You can change this to, say, 44 but keep the number constant for all image views.
Finally, widthToPreserve
HAS to be a minimum of 34 (which means the overall Rect width has to be 68 or more) because that's the width of the rounded edge in the original image.
Of course, you can simply all this by having a smaller image, if your target image view height is 44.
This code works:
-(void)viewDidAppear:(BOOL)animated
{
UIImage *img = [UIImage imageNamed:@"img"];
UIImageView *view1 = [self getImageViewFromImage:img widthToPreserve:34 fitInRect:CGRectMake(20, 20, 100, 77)];
UIImageView *view2 = [self getImageViewFromImage:img widthToPreserve:34 fitInRect:CGRectMake(20, 120, 250, 77)];
[self.view addSubview:view1];
[self.view addSubview:view2];
}
-(UIImageView*)getImageViewFromImage:(UIImage*)image widthToPreserve:(float)width fitInRect:(CGRect)rect
{
CGImageRef left, middle, right;
CGRect leftRect, middleRect, rightRect;
UIImage *leftImage, *middleImage, *rightImage;
UIImageView *leftView, *middleView, *rightView;
// calculate CGRect values for the original image
leftRect = CGRectMake(0, 0, width, image.size.height);
middleRect = CGRectMake(width, 0, image.size.width - 2*width, image.size.height);
rightRect = CGRectMake(image.size.width - width, 0, width, image.size.height);
left = CGImageCreateWithImageInRect([image CGImage], leftRect);
middle = CGImageCreateWithImageInRect([image CGImage], middleRect);
right = CGImageCreateWithImageInRect([image CGImage], rightRect);
leftImage = [UIImage imageWithCGImage:left];
middleImage = [UIImage imageWithCGImage:middle];
rightImage = [UIImage imageWithCGImage:right];
leftView = [[UIImageView alloc] initWithImage:leftImage];
middleView = [[UIImageView alloc] initWithImage:middleImage];
rightView = [[UIImageView alloc] initWithImage:rightImage];
//make your image subviews, with scaling on the middle view
[leftView setFrame:CGRectMake(0, 0, width, rect.size.height)];
[middleView setFrame:CGRectMake(width, 0, rect.size.width - 2*width, rect.size.height)];
[rightView setFrame:CGRectMake(rect.size.width - width, 0, width, rect.size.height)];
//add your 3 subviews into a single image view
UIImageView *imgView = [[UIImageView alloc] initWithFrame:rect];
[imgView addSubview:leftView];
[imgView addSubview:middleView];
[imgView addSubview:rightView];
CGImageRelease(left);
CGImageRelease(middle);
CGImageRelease(right);
return imgView;
}
Screenshot: