iOS 开发之Resize UIimage的三种方法

来源:互联网 发布:见一落叶而知岁之将暮 编辑:程序博客网 时间:2024/05/17 23:26

Method 1: Using UIKit

+ (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize;{    // Create a graphics image context    UIGraphicsBeginImageContext(newSize);    // Tell the old image to draw in this new context, with the desired    // new size    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];    // Get the new image from the context    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();    // End the context    UIGraphicsEndImageContext();    // Return the new image.    return newImage;}

This method is very simple, and works great. It will also deal with the UIImageOrientation for you, meaning that you don't have to care whether the camera was sideways when the picture was taken.However, this method is not thread safe, and since thumbnailing is a relatively expensive operation (approximately ~2.5s on a 3G for a 1600 x 1200 pixel image), this is very much an operation you may want to do in the background, on a separate thread.

Method 2: Using CoreGraphics

+ (UIImage*)imageWithImage:(UIImage*)sourceImage scaledToSize:(CGSize)newSize;{    CGFloat targetWidth = newSize.width;    CGFloat targetHeight = newSize.height;    CGImageRef imageRef = [sourceImage CGImage];    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);    if (bitmapInfo == kCGImageAlphaNone) {        bitmapInfo = kCGImageAlphaNoneSkipLast;    }    CGContextRef bitmap;    if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) {        bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);    } else {        bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);    }       if (sourceImage.imageOrientation == UIImageOrientationLeft) {        CGContextRotateCTM (bitmap, M_PI_2); // + 90 degrees        CGContextTranslateCTM (bitmap, 0, -targetHeight);    } else if (sourceImage.imageOrientation == UIImageOrientationRight) {        CGContextRotateCTM (bitmap, -M_PI_2); // - 90 degrees        CGContextTranslateCTM (bitmap, -targetWidth, 0);    } else if (sourceImage.imageOrientation == UIImageOrientationUp) {        // NOTHING    } else if (sourceImage.imageOrientation == UIImageOrientationDown) {        CGContextTranslateCTM (bitmap, targetWidth, targetHeight);        CGContextRotateCTM (bitmap, -M_PI); // - 180 degrees    }    CGContextDrawImage(bitmap, CGRectMake(0, 0, targetWidth, targetHeight), imageRef);    CGImageRef ref = CGBitmapContextCreateImage(bitmap);    UIImage* newImage = [UIImage imageWithCGImage:ref];    CGContextRelease(bitmap);    CGImageRelease(ref);    return newImage; }

The benefit of this method is that it is thread-safe, plus it takes care of all the small things (using correct color space and bitmap info, dealing with image orientation) that the UIKit version does.

How Do I Resize and Maintain Aspect Ratio (like the AspectFill option)?

It is very similar to the method above, and it looks like this:

+ (UIImage*)imageWithImage:(UIImage*)sourceImage scaledToSizeWithSameAspectRatio:(CGSize)targetSize;{      CGSize imageSize = sourceImage.size;    CGFloat width = imageSize.width;    CGFloat height = imageSize.height;    CGFloat targetWidth = targetSize.width;    CGFloat targetHeight = targetSize.height;    CGFloat scaleFactor = 0.0;    CGFloat scaledWidth = targetWidth;    CGFloat scaledHeight = targetHeight;    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);    if (CGSizeEqualToSize(imageSize, targetSize) == NO) {        CGFloat widthFactor = targetWidth / width;        CGFloat heightFactor = targetHeight / height;        if (widthFactor > heightFactor) {            scaleFactor = widthFactor; // scale to fit height        }        else {            scaleFactor = heightFactor; // scale to fit width        }        scaledWidth  = width * scaleFactor;        scaledHeight = height * scaleFactor;        // center the image        if (widthFactor > heightFactor) {            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;         }        else if (widthFactor < heightFactor) {            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;        }    }         CGImageRef imageRef = [sourceImage CGImage];    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);    if (bitmapInfo == kCGImageAlphaNone) {        bitmapInfo = kCGImageAlphaNoneSkipLast;    }    CGContextRef bitmap;    if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) {        bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);    } else {        bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);    }       // In the right or left cases, we need to switch scaledWidth and scaledHeight,    // and also the thumbnail point    if (sourceImage.imageOrientation == UIImageOrientationLeft) {        thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x);        CGFloat oldScaledWidth = scaledWidth;        scaledWidth = scaledHeight;        scaledHeight = oldScaledWidth;        CGContextRotateCTM (bitmap, M_PI_2); // + 90 degrees        CGContextTranslateCTM (bitmap, 0, -targetHeight);    } else if (sourceImage.imageOrientation == UIImageOrientationRight) {        thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x);        CGFloat oldScaledWidth = scaledWidth;        scaledWidth = scaledHeight;        scaledHeight = oldScaledWidth;        CGContextRotateCTM (bitmap, -M_PI_2); // - 90 degrees        CGContextTranslateCTM (bitmap, -targetWidth, 0);    } else if (sourceImage.imageOrientation == UIImageOrientationUp) {        // NOTHING    } else if (sourceImage.imageOrientation == UIImageOrientationDown) {        CGContextTranslateCTM (bitmap, targetWidth, targetHeight);        CGContextRotateCTM (bitmap, -M_PI); // - 180 degrees    }    CGContextDrawImage(bitmap, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), imageRef);    CGImageRef ref = CGBitmapContextCreateImage(bitmap);    UIImage* newImage = [UIImage imageWithCGImage:ref];    CGContextRelease(bitmap);    CGImageRelease(ref);    return newImage; }

The method we employ here is to create a bitmap with the desired size, but draw an image that is actually larger, thus maintaining the aspect ratio.

原创粉丝点击