views:

4179

answers:

6

Hey guys! I create a UIButton instance(named "button") with a image use [UIButton setImage:forState:] function, the button.frame is larger than the image's size. Now I want to scale this button's image smaller. I had tried to change button.imageView.frame, button.imageView.bounds and button.imageView.contentMode, but all seem ineffective.

Hopefully someone can help me how to scale a UIButton's imageView.Thanks!

my create UIButton instance code:

UIButton *button = [[UIButton alloc] init];
[button setImage:image forState:UIControlStateNormal];

my try to scale the image code:

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.bounds = CGRectMake(0, 0, 70, 70);

and:

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.frame = CGRectMake(0, 0, 70, 70);
+4  A: 
    UIButton *button= [[UIButton alloc] initWithFrame:CGRectMake(0,0,70,70)];
    button.buttonType = UIButtonTypeCustom;
    UIImage *buttonImage = [UIImage imageNamed:@"image.png"];

    UIImage *stretchableButtonImage = [buttonImage stretchableImageWithLeftCapWidth:12 topCapHeight:0]; 
    [button setBackgroundImage:stretchableButtonImage forState:UIControlStateNormal];
EEE
@EEE Thank you.But there are 2 problem: 1. My question is use the UIButton's _imageView variable, not the _backgroundView variable. Have I to do it with backgroundView? 2. the function [UIImage stretchableImageWithLeftCapWidth:topCapHeight:] can only to make image larger, but can't make image smaller. Thanks all the same, and your answer solves my another question:I want to draw a title on the button with the image behind. I think the _backgroundImage can help me. Does this question has other better answer?
vcLwei
I see what you are trying to do and this is the way. if your image is bigger, then resize it using a tool, and everything you want to do will be done. Don't waste your time with_imageview. By the way if you like this asnwer, you can vote it up, and accept it
EEE
You can resize your image in Preview program in MacOS. Just open the image and selet tools-->Adjustsize
EEE
@EEE Yes,I can resize my image use a tool. But in my application sometimes I need the bigger image too, I don't want to two similar images only difference at size, that too waste space. And another way to do solve my question is that I can use CGBitmapContext to get a smaller image, but I guess this way is inconvenience compara to using _imageview.The reason I did not vote it up is my reputation is less than 15, actually I really want to do that. Thanks!
vcLwei
A: 

I can't get a solution use by _imageView, but I can use a CGContextRef to solve it. It use the UIGraphicsGetCurrentContext to get the currentContextRef and draw a image in currentContextRef, and then scale or rotate the image and create a new image. But it's not perfect.

the code:

-(UIImage*) scaleAndRotateImage:(UIImage*)photoimage width:(CGFloat)bounds_width height:(CGFloat)bounds_height;
{
    CGImageRef imgRef = photoimage.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);

    bounds.size.width = bounds_width;
    bounds.size.height = bounds_height;

    CGFloat scaleRatio = bounds.size.width / width;
    CGFloat scaleRatioheight = bounds.size.height / height;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = photoimage.imageOrientation;
    switch(orient)
    {
        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid?image?orientation"];
            break;
    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft)
    {
        CGContextScaleCTM(context, -scaleRatio, scaleRatioheight);
        CGContextTranslateCTM(context, -height, 0);
    }
    else
    {
        CGContextScaleCTM(context, scaleRatio, -scaleRatioheight);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return imageCopy;
}
vcLwei
A: 

like this can solve your problem:

  • (UIImage*)resizedImage:(UIImage*)image { CGRect frame = CGRectMake(0, 0, 60, 60); UIGraphicsBeginImageContext(frame.size); [image drawInRect:frame]; UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();

    return resizedImage; }

huangkui
+2  A: 

use

button.contentMode = UIViewContentModeScaleToFill;

not

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
pavelpanov
This works great in combination with [button setBackgroundImage:forState:]. Thanks.
Jason DeFontes
A: 

I found this solution.

1) Subclass the following methods of UIButton

+ (id)buttonWithType:(UIButtonType)buttonType {
    MyButton *toReturn = [super buttonWithType:buttonType];
    toReturn.imageView.contentMode = UIViewContentModeScaleAspectFit;
    return toReturn;
}

- (CGRect)imageRectForContentRect:(CGRect)contentRect {
    return contentRect;
}

And it works well.

marcio
A: 

I just ran into this same problem, and there's a possible answer in this question:

http://stackoverflow.com/questions/1063019/why-does-a-custom-uibutton-image-does-not-resize-in-interface-builder

Essentially, use the backgroundimage property instead, which does get scaled.

JosephH