Blog Links

Objective C – correctly scaling button & background images

I often find a need to scale buttons and background graphics to the correct size, but leave the edges at the same scale. So taking the button in Fig 1, if you simply scale it normally it looks like Fig 2, however I want to keep the borders the same like in Fig 3.

So I split the image into 9 parts, and then scale up and down selectively altering different parts of the image.

  • Parts A C G & F stay the same,
  • Parts B & H are scaled horizontally only
  • Parts D & F are scaled vertically only
  • Parts E are scaled vertically & horizontally

You can do this manually in photoshop, but I wrote a Objective C Category (Extenson of UIImage) to create these scaled images.

So the following code will take the original image and scale it up to 100×100 using an 8pixel border around the image which is not scaled.

UIIMage *image = [[UIImage imageNamed:@"orange.png"] scaleWithBorder:8 size:CGSizeMake(100,100)];

Source Code

 

UIImage+BorderedImageScaler.h

#import
@interface UIImage (BorderedImageScaler)
-(UIImage*)scaleWithBorder:(int)borderSize size:(CGSize)newsize;
@end

UIImage+BorderedImageScaler.m

#import "UIImage+BorderedImageScaler.h"

@implementation UIImage (BorderedImageScaler)

-(UIImage*)scaleWithBorder:(int)borderSize size:(CGSize)newsize{
    //Returns a new image scale to newsize
    //However a border around the edge bordersize pixels wide is not scaled
    //This allows button images to be scaled but the edges with bevels/shadows etc keep the same size.

    //The image is split into 9 parts

    // 1 2 3
    // 4 5 6
    // 7 8 9

    //Parts 1 3 7 9 do not scale
    //      2 & 8 scale horizontally only
    //      4 &6 scale vertically only
    //      5 scales horizontally and vertically

    CGSize currentSize = self.size;

    CGImageRef imageRef = self.CGImage;
    CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                                newsize.width,
                                                newsize.height,
                                                CGImageGetBitsPerComponent(imageRef),
                                                0,
                                                CGImageGetColorSpace(imageRef),
                                                kCGImageAlphaPremultipliedFirst);

    CGImageRef cgbaseimage = [self CGImage];

    int a,b,c,d;
    a=0;
    b=borderSize;
    c=currentSize.width-borderSize;
    d=currentSize.width-borderSize-borderSize;

    int e,f,g,h;
    e=0;
    f=borderSize;
    g=currentSize.height-borderSize;
    h=currentSize.height-borderSize-borderSize;    

    int z,y,x,w;
    z=0;
    y=borderSize;
    x=newsize.width-borderSize;
    w=newsize.width-borderSize-borderSize; 

    int s,t,u,v;
    t=newsize.height-borderSize;
    u=borderSize;
    v=0;
    s=newsize.height-borderSize-borderSize;

    CGImageRef im1 = CGImageCreateWithImageInRect(cgbaseimage, CGRectMake(a,e,b,f));
    CGContextDrawImage(bitmap, CGRectMake(z,t,borderSize,borderSize), im1);
    CGImageRelease(im1);

    im1 = CGImageCreateWithImageInRect(cgbaseimage, CGRectMake(b,e,h,borderSize));
    CGContextDrawImage(bitmap, CGRectMake(y,t,w,borderSize), im1);
    CGImageRelease(im1);

    im1 = CGImageCreateWithImageInRect(cgbaseimage, CGRectMake(c,e,borderSize,borderSize));
    CGContextDrawImage(bitmap, CGRectMake(x,t,borderSize,borderSize), im1);
    CGImageRelease(im1);

    im1 = CGImageCreateWithImageInRect(cgbaseimage, CGRectMake(a,f,borderSize,h));
    CGContextDrawImage(bitmap, CGRectMake(z,u,borderSize,s), im1);
    CGImageRelease(im1);

    im1 = CGImageCreateWithImageInRect(cgbaseimage, CGRectMake(b,f,d,h));
    CGContextDrawImage(bitmap, CGRectMake(y,u,w,s), im1);
    CGImageRelease(im1);

    im1 = CGImageCreateWithImageInRect(cgbaseimage, CGRectMake(c,f,borderSize,h));
    CGContextDrawImage(bitmap, CGRectMake(x,u,borderSize,s), im1);
    CGImageRelease(im1);

    im1 = CGImageCreateWithImageInRect(cgbaseimage, CGRectMake(a,g,borderSize,borderSize));
    CGContextDrawImage(bitmap, CGRectMake(z,v,borderSize,borderSize), im1);
    CGImageRelease(im1);

    im1 = CGImageCreateWithImageInRect(cgbaseimage, CGRectMake(b,g,d,borderSize));
    CGContextDrawImage(bitmap, CGRectMake(y,v,w,borderSize), im1);
    CGImageRelease(im1);

    im1 = CGImageCreateWithImageInRect(cgbaseimage, CGRectMake(c,g,borderSize,borderSize));
    CGContextDrawImage(bitmap, CGRectMake(x,v,borderSize,borderSize), im1);
    CGImageRelease(im1);

    CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
    UIImage *ret =  [UIImage imageWithCGImage:newImageRef];
    CGImageRelease(newImageRef);
    CGContextRelease(bitmap);
    return ret;

}

@end

Download

Download the code here

If this has been useful to you, and you would like to buy me a coffee, or help towards my monthly server costs please click here to make a donation via paypal.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>