iOS2012. 9. 10. 21:57

iOS 개발 하다 보니 image를 crop 하거나 resize를 해야 하는 경우가 많더구요.

구글링 해보니 괜찮게 만들어 놓은 소스도 많아서 참고해서 UIImage에 Category로 만들어서 사용하고 있습니다. 


  1. @implementation UIImage ( NBUIImageCrop )
  2. - (UIImage *)crop:(CGRect)rect {
  3.     if (self.scale > 1.0f) {
  4.         rect = CGRectMake(rect.origin.* self.scale,
  5.                           rect.origin.* self.scale,
  6.                           rect.size.width * self.scale,
  7.                           rect.size.height * self.scale);
  8.     }
  9.    
  10.     if ([self imageOrientation] == UIImageOrientationLeft) {
  11.         rect.size = CGSizeMake(rect.size.height, rect.size.width);
  12.         rect.size = CGSizeMake(rect.size.height, rect.size.width);
  13.         rect.origin = CGPointMake(rect.origin.y, rect.origin.x);
  14.     }
  15.     else if ([self imageOrientation] == UIImageOrientationRight) {
  16.         rect.size = CGSizeMake(rect.size.height, rect.size.width);
  17.         rect.origin = CGPointMake(rect.origin.y, rect.origin.x);
  18.     }
  19.  
  20.     CGImageRef imageRef = CGImageCreateWithImageInRect(self.CGImage, rect);
  21.     UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
  22.     CGImageRelease(imageRef);
  23.     return result;
  24. }
  25.  
  26. - (UIImage *)resizeToFitWidth:(CGFloat)width
  27. {
  28.     CGSize size = CGSizeMake(width, self.size.height * width/self.size.width);
  29.     UIGraphicsBeginImageContext(size);
  30.     [self drawInRect:CGRectMake(0,0,size.width,size.height)];
  31.     UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
  32.     UIGraphicsEndImageContext();
  33.     return newImage;
  34. }

Posted by 다오나무
iOS2012. 9. 3. 17:21

UIImageView를 사용할 경우 UIImageView의 프레임 사이즈에 맞춰 이미지 비율에 따라 이미지 사이즈를 쉽게 재조정할 수 있지만

뷰상에서 특정 UIImage를 drawRect하는 경우에는 비율에 맞춰서 이미지 사이즈나 스케일을 재조정하는게 쉽지 않다.

따라서 다음과 같은 UIImage의 카테고리를 사용해 이미지 비율에 따라 UIImage스케일을 재조정한다.



카테고리의 헤더 파일 

#import <Foundation/Foundation.h>


@interface UIImage (UIImageSizeExtention)


- (UIImage *)fixImageSize;

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

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

- (UIImage *)scaleProportionlyToWidth:(CGFloat)width;

- (UIImage *)scaleProportionlyToHeight:(CGFloat)height;

- (UIImage *)cropToRect:(CGRect)newRect;


@end   


카테고리의 실행 파일

#import "UIImage+SizeExtention.h"


@implementation UIImage (UIImageSizeExtention)
 

#pragma mark -

#pragma mark Basic


- (UIImage*)fixImageSize 

{

    // Fix some strange bug

    UIGraphicsBeginImageContext(self.size);

    [self drawInRect:CGRectMake(00self.size.widthself.size.height)];

    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return newImage;

}


#pragma mark -

#pragma mark Fit (Combination)


- (UIImage *)fitToSize:(CGSize)newSize {

    float originalProportion = self.size.width/self.size.height;

    float targetProportion = newSize.width/newSize.height;

    float scaleProportion = newSize.width/self.size.width;

    UIImage *targetImage;

    

    if (targetProportion == originalProportion) {

        // Same Proportion

        // Do not have to crop, Direct scale

        targetImage = [self scaleToSize:newSize];

    } else if (targetProportion) {

        // Relative Landscape

        // Crop Rect

        CGFloat originX = self.size.width*scaleProportion/2 - newSize.width/2;

        CGRect cropRect = CGRectMake(originX, 0, newSize.width, newSize.height);

        // Scale to Height, Crop

        targetImage = [[self scaleProportionlyToHeight:newSize.heightcropToRect:cropRect];

    } else {

        // Relative Portrait

        // Scale to Width

        CGFloat originY = self.size.height*scaleProportion/2 - newSize.height/2;

        CGRect cropRect = CGRectMake(0, originY, newSize.width, newSize.height);

        targetImage = [[self scaleProportionlyToWidth:newSize.widthcropToRect:cropRect];

    }

   

   return targetImage;

}

               

#pragma mark -

#pragma mark Scale

               

- (UIImage *)scaleToSize:(CGSize)newSize {

    UIImage *targetImage = [self fixImageSize];

    // Prepare new size context

    UIGraphicsBeginImageContext(newSize);

    // Get current image

    CGContextRef context = UIGraphicsGetCurrentContext();

   

    // Change the coordinate from CoreGraphics (Quartz2D) to UIView

    CGContextTranslateCTM(context, 0.0, newSize.height);

    CGContextScaleCTM(context, 1.0, -1.0);

    // Draw (Scale)

    // The size of this drawRect is for scale

    CGRect drawRect = CGRectMake(00, newSize.width, newSize.height);

    CGContextDrawImage(context, drawRect, targetImage.CGImage);

   

    // Get result and clean

    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

   

    return scaledImage;

}


- (UIImage *)scaleProportionlyToWidth:(CGFloat)width {

    float originalProportion = self.size.width/self.size.height;

    CGFloat height = width/originalProportion;

    return [self scaleToSize:CGSizeMake(width, height)];

}


- (UIImage *)scaleProportionlyToHeight:(CGFloat)height {

    float originalProportion = self.size.width/self.size.height;

    CGFloat width = height*originalProportion;

    return [self scaleToSize:CGSizeMake(width, height)];

}

               

#pragma mark -

#pragma mark Crop

               

- (UIImage *)cropToRect:(CGRect)newRect {

    UIImage *targetImage = [self fixImageSize];

    // Prepare new rect context

    UIGraphicsBeginImageContext(newRect.size);

    // Get current image

    CGContextRef context = UIGraphicsGetCurrentContext();

   

    // Change the coordinate from CoreGraphics (Quartz2D) to UIView

    CGContextTranslateCTM(context, 0.0, newRect.size.height);

    CGContextScaleCTM(context, 1.0, -1.0);

    // Draw (Crop)

    // This drawRect is for crop

    CGRect clippedRect = CGRectMake(00, newRect.size.width, newRect.size.height);

    CGContextClipToRect(context, clippedRect);

    CGRect drawRect = CGRectMake(newRect.origin.x*(-1), newRect.origin.y*(-1), targetImage.size.width, targetImage.size.height);

    CGContextDrawImage(context, drawRect, targetImage.CGImage);

   

    UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return croppedImage;

}    

@end



위의 카테고리를 다음과 같이 사용하였다.

UIImage *image = [UIImage imageNamed:/*Image name*/];


if
 (image.size.width > image.size.height

{

// If the width of a image is longer than the height
// rescale to width

image = [image scaleProportionlyToWidth:/*Image width*/];

}

else

{        

// If the height of a image is longer than the width
// recale to height

image = [image scaleProportionlyToHeight: /*Image height*/];

}


CGRect drawRect = CGRectMake(0, 0, image.size.width, image.size.height);


[image drawInRect:drawRect];


Posted by 다오나무