choise choise - 4 months ago 33
iOS Question

resize and crop image centered

so currently i'm trying to crop and resize a picture to fit it into a specific size without losing the ratio.

a small image to show what i mean:

alt text

i played a bit with vocaro's categories but they don't work with png's and have problems with gifs. also the image doesn't get cropped.

does anyone have a suggestion how to do this resizing the best way or probably have a link to an existing library/categorie/whatever?

thanks for all hints!

p.s.: does ios implement a "select a excerpt" so that i have the right ratio and only have to scale it?!

par par
Answer

This method will do what you want and is a category of UIImage for ease of use. I went with resize then crop, you could switch the code around easily enough if you want crop then resize. The bounds checking in the function is purely illustrative. You might want to do something different, for example center the crop rect relative to the outputImage dimensions but this ought to get you close enough to make whatever other changes you need.

@implementation UIImage( resizeAndCropExample )

- (UIImage *) resizeToSize:(CGSize) newSize thenCropWithRect:(CGRect) cropRect {
    CGContextRef                context;
    CGImageRef                  imageRef;
    CGSize                      inputSize;
    UIImage                     *outputImage = nil;
    CGFloat                     scaleFactor, width;

    // resize, maintaining aspect ratio:

    inputSize = self.size;
    scaleFactor = newSize.height / inputSize.height;
    width = roundf( inputSize.width * scaleFactor );

    if ( width > newSize.width ) {
        scaleFactor = newSize.width / inputSize.width;
        newSize.height = roundf( inputSize.height * scaleFactor );
    } else {
        newSize.width = width;
    }

    UIGraphicsBeginImageContext( newSize );

    context = UIGraphicsGetCurrentContext();

    // added 2016.07.29, flip image vertically before drawing:
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, 0, newSize.height);
    CGContextScaleCTM(context, 1, -1);
    CGContextDrawImage(context, CGRectMake(0, 0, newSize.width, newSize.height, self.CGImage);

//  // alternate way to draw
//  [self drawInRect: CGRectMake( 0, 0, newSize.width, newSize.height )];

    CGContextRestoreGState(context);

    outputImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    inputSize = newSize;

    // constrain crop rect to legitimate bounds
    if ( cropRect.origin.x >= inputSize.width || cropRect.origin.y >= inputSize.height ) return outputImage;
    if ( cropRect.origin.x + cropRect.size.width >= inputSize.width ) cropRect.size.width = inputSize.width - cropRect.origin.x;
    if ( cropRect.origin.y + cropRect.size.height >= inputSize.height ) cropRect.size.height = inputSize.height - cropRect.origin.y;

    // crop
    if ( ( imageRef = CGImageCreateWithImageInRect( outputImage.CGImage, cropRect ) ) ) {
        outputImage = [[[UIImage alloc] initWithCGImage: imageRef] autorelease];
        CGImageRelease( imageRef );
    }

    return outputImage;
}

@end
Comments