当前位置: 动力学知识库 > 问答 > 编程问答 >

iphone - How do i resize UIImages without the pain?

问题描述:

I've seen:

  • Accusations that various UIImage resizing code is wrong and has bugs
  • Resizing code which comes out with low quality images
  • Resizing code

    which flips the image

  • Resizing code which doesn't work correctly on

    portrait camera photos specifically

Is there a piece of code for resizing/cropping a UIImage that somebody could recommend?

网友答案:

I use this category, which is a category that provides UIImage a series of resizing methods, which effectively supports UIViewContentModeScaleToFill, UIViewContentModeScaleAspectFill, and UIViewContentModeScaleAspectFit.

I use this primarily for creating my thumbnail images (using my imageByScalingAspectFillSize) and do this with images of varying formats without incident.

UIImage+SimpleResize.h:

//  UIImage+SimpleResize.h
//
//  Created by Robert Ryan on 5/19/11.

#import <Foundation/Foundation.h>

/** Image resizing category.
 *
 *  Modified by Robert Ryan on 5/19/11.
 *
 *  Inspired by http://ofcodeandmen.poltras.com/2008/10/30/undocumented-uiimage-resizing/
 *  but adjusted to support AspectFill and AspectFit modes.
 */

@interface UIImage (SimpleResize)

/** Resize the image to be the required size, stretching it as needed.
 *
 * @param newSize      The new size of the image.
 * @param contentMode  The `UIViewContentMode` to be applied when resizing image.
 *                     Either `UIViewContentModeScaleToFill`, `UIViewContentModeScaleAspectFill`, or
 *                     `UIViewContentModeScaleAspectFit`.
 *
 * @return             Return `UIImage` of resized image.
 */

- (UIImage*)imageByScalingToSize:(CGSize)newSize contentMode:(UIViewContentMode)contentMode;

/** Crop the image to be the required size.
 *
 * @param bounds       The bounds to which the new image should be cropped.
 *
 * @return             Cropped `UIImage`.
 */

- (UIImage *)imageByCroppingToBounds:(CGRect)bounds;

/** Resize the image to be the required size, stretching it as needed.
 *
 * @param newSize The new size of the image.
 *
 * @return        Resized `UIImage` of resized image.
 */

- (UIImage*)imageByScalingToFillSize:(CGSize)newSize;

/** Resize the image to fill the rectange of the specified size, preserving the aspect ratio, trimming if needed.
 *
 * @param newSize The new size of the image.
 *
 * @return        Return `UIImage` of resized image.
 */

- (UIImage*)imageByScalingAspectFillSize:(CGSize)newSize;

/** Resize the image to fit within the required size, preserving the aspect ratio, with no trimming taking place.
 *
 * @param newSize The new size of the image.
 *
 * @return        Return `UIImage` of resized image.
 */

- (UIImage*)imageByScalingAspectFitSize:(CGSize)newSize;

@end

UIImage+SimpleResize.m:

//  UIImage+SimpleResize.m
//
//  Created by Robert Ryan on 5/19/11.

#import "UIImage+SimpleResize.h"

@implementation UIImage (SimpleResize)

- (UIImage*)imageByScalingToSize:(CGSize)newSize contentMode:(UIViewContentMode)contentMode
{
    if (contentMode == UIViewContentModeScaleToFill)
    {
        return [self imageByScalingToFillSize:newSize];
    }
    else if ((contentMode == UIViewContentModeScaleAspectFill) ||
             (contentMode == UIViewContentModeScaleAspectFit))
    {
        CGFloat horizontalRatio   = self.size.width  / newSize.width;
        CGFloat verticalRatio     = self.size.height / newSize.height;
        CGFloat ratio;

        if (contentMode == UIViewContentModeScaleAspectFill)
            ratio = MIN(horizontalRatio, verticalRatio);
        else
            ratio = MAX(horizontalRatio, verticalRatio);

        CGSize  sizeForAspectScale = CGSizeMake(self.size.width / ratio, self.size.height / ratio);

        UIImage *image = [self imageByScalingToFillSize:sizeForAspectScale];

        // if we're doing aspect fill, then the image still needs to be cropped

        if (contentMode == UIViewContentModeScaleAspectFill)
        {
            CGRect  subRect = CGRectMake(floor((sizeForAspectScale.width - newSize.width) / 2.0),
                                         floor((sizeForAspectScale.height - newSize.height) / 2.0),
                                         newSize.width,
                                         newSize.height);
            image = [image imageByCroppingToBounds:subRect];
        }

        return image;
    }

    return nil;
}

- (UIImage *)imageByCroppingToBounds:(CGRect)bounds
{
    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], bounds);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return croppedImage;
}

- (UIImage*)imageByScalingToFillSize:(CGSize)newSize
{
    UIGraphicsBeginImageContext(newSize);
    [self drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

- (UIImage*)imageByScalingAspectFillSize:(CGSize)newSize
{
    return [self imageByScalingToSize:newSize contentMode:UIViewContentModeScaleAspectFill];
}

- (UIImage*)imageByScalingAspectFitSize:(CGSize)newSize
{
    return [self imageByScalingToSize:newSize contentMode:UIViewContentModeScaleAspectFit];
}

@end
网友答案:

If you are talking about just the UIImage which doesnt contain metadata its just a matter of starting creating a graphics context and calling the uiimage draw in context method:

- (UIImage*)resizeImage:(UIImage*)jpeg withSize:(CGSize)newSize
{   
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [jpeg drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();

    return resizedImage;
}

IF what you want is to resize images that contain metadata like read from the disk or something, perform the previews method and when re-saving use the original source dictionary.

分享给朋友:
您可能感兴趣的文章:
随机阅读: