PageRenderTime 51ms CodeModel.GetById 16ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/google-toolbox-for-mac/iPhone/GTMUIImage+Resize.m

http://macfuse.googlecode.com/
Objective C | 186 lines | 129 code | 26 blank | 31 comment | 14 complexity | 10e3f5052dc4dbfcb514e701571e5cf9 MD5 | raw file
  1//
  2//  GTMUIImage+Resize.m
  3//
  4//  Copyright 2009 Google Inc.
  5//
  6//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7//  use this file except in compliance with the License.  You may obtain a copy
  8//  of the License at
  9//
 10//  http://www.apache.org/licenses/LICENSE-2.0
 11//
 12//  Unless required by applicable law or agreed to in writing, software
 13//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 14//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 15//  License for the specific language governing permissions and limitations under
 16//  the License.
 17//
 18
 19#import "GTMUIImage+Resize.h"
 20#import "GTMDefines.h"
 21
 22GTM_INLINE CGSize swapWidthAndHeight(CGSize size) {
 23  CGFloat  tempWidth = size.width;
 24
 25  size.width  = size.height;
 26  size.height = tempWidth;
 27
 28  return size;
 29}
 30
 31@implementation UIImage (GTMUIImageResizeAdditions)
 32
 33- (UIImage *)gtm_imageByResizingToSize:(CGSize)targetSize
 34                   preserveAspectRatio:(BOOL)preserveAspectRatio
 35                             trimToFit:(BOOL)trimToFit {
 36  CGSize imageSize = [self size];
 37  if (imageSize.height < 1 || imageSize.width < 1) {
 38    return nil;
 39  }
 40  if (targetSize.height < 1 || targetSize.width < 1) {
 41    return nil;
 42  }
 43  CGFloat aspectRatio = imageSize.width / imageSize.height;
 44  CGFloat targetAspectRatio = targetSize.width / targetSize.height;
 45  CGRect projectTo = CGRectZero;
 46  if (preserveAspectRatio) {
 47    if (trimToFit) {
 48      // Scale and clip image so that the aspect ratio is preserved and the
 49      // target size is filled.
 50      if (targetAspectRatio < aspectRatio) {
 51        // clip the x-axis.
 52        projectTo.size.width = targetSize.height * aspectRatio;
 53        projectTo.size.height = targetSize.height;
 54        projectTo.origin.x = (targetSize.width - projectTo.size.width) / 2;
 55        projectTo.origin.y = 0;
 56      } else {
 57        // clip the y-axis.
 58        projectTo.size.width = targetSize.width;
 59        projectTo.size.height = targetSize.width / aspectRatio;
 60        projectTo.origin.x = 0;
 61        projectTo.origin.y = (targetSize.height - projectTo.size.height) / 2;
 62      }
 63    } else {
 64      // Scale image to ensure it fits inside the specified targetSize.
 65      if (targetAspectRatio < aspectRatio) {
 66        // target is less wide than the original.
 67        projectTo.size.width = targetSize.width;
 68        projectTo.size.height = projectTo.size.width / aspectRatio;
 69        targetSize = projectTo.size;
 70      } else {
 71        // target is wider than the original.
 72        projectTo.size.height = targetSize.height;
 73        projectTo.size.width = projectTo.size.height * aspectRatio;
 74        targetSize = projectTo.size;
 75      }
 76    } // if (clip)
 77  } else {
 78    // Don't preserve the aspect ratio.
 79    projectTo.size = targetSize;
 80  }
 81
 82  projectTo = CGRectIntegral(projectTo);
 83  // There's no CGSizeIntegral, so we fake our own.
 84  CGRect integralRect = CGRectZero;
 85  integralRect.size = targetSize;
 86  targetSize = CGRectIntegral(integralRect).size;
 87
 88  // Resize photo. Use UIImage drawing methods because they respect
 89  // UIImageOrientation as opposed to CGContextDrawImage().
 90  UIGraphicsBeginImageContext(targetSize);
 91  [self drawInRect:projectTo];
 92  UIImage* resizedPhoto = UIGraphicsGetImageFromCurrentImageContext();
 93  UIGraphicsEndImageContext();
 94  return resizedPhoto;
 95}
 96
 97// Based on code by Trevor Harmon:
 98// http://vocaro.com/trevor/blog/wp-content/uploads/2009/10/UIImage+Resize.h
 99// http://vocaro.com/trevor/blog/wp-content/uploads/2009/10/UIImage+Resize.m
100- (UIImage *)gtm_imageByRotating:(UIImageOrientation)orientation {
101  CGRect bounds = CGRectZero;
102  CGRect rect = CGRectZero;
103  CGAffineTransform transform = CGAffineTransformIdentity;
104
105  bounds.size = [self size];
106  rect.size = [self size];
107
108  switch (orientation) {
109    case UIImageOrientationUp:
110      return [UIImage imageWithCGImage:[self CGImage]];
111
112    case UIImageOrientationUpMirrored:
113      transform = CGAffineTransformMakeTranslation(rect.size.width, 0.0);
114      transform = CGAffineTransformScale(transform, -1.0, 1.0);
115      break;
116
117    case UIImageOrientationDown:
118      transform = CGAffineTransformMakeTranslation(rect.size.width,
119                                                   rect.size.height);
120      transform = CGAffineTransformRotate(transform, M_PI);
121      break;
122
123    case UIImageOrientationDownMirrored:
124      transform = CGAffineTransformMakeTranslation(0.0, rect.size.height);
125      transform = CGAffineTransformScale(transform, 1.0, -1.0);
126      break;
127
128    case UIImageOrientationLeft:
129      bounds.size = swapWidthAndHeight(bounds.size);
130      transform = CGAffineTransformMakeTranslation(0.0, rect.size.width);
131      transform = CGAffineTransformRotate(transform, -M_PI_2);
132      break;
133
134    case UIImageOrientationLeftMirrored:
135      bounds.size = swapWidthAndHeight(bounds.size);
136      transform = CGAffineTransformMakeTranslation(rect.size.height,
137                                                   rect.size.width);
138      transform = CGAffineTransformScale(transform, -1.0, 1.0);
139      transform = CGAffineTransformRotate(transform, -M_PI_2);
140      break;
141
142    case UIImageOrientationRight:
143      bounds.size = swapWidthAndHeight(bounds.size);
144      transform = CGAffineTransformMakeTranslation(rect.size.height, 0.0);
145      transform = CGAffineTransformRotate(transform, M_PI_2);
146      break;
147
148    case UIImageOrientationRightMirrored:
149      bounds.size = swapWidthAndHeight(bounds.size);
150      transform = CGAffineTransformMakeScale(-1.0, 1.0);
151      transform = CGAffineTransformRotate(transform, M_PI_2);
152      break;
153
154    default:
155      _GTMDevAssert(false, @"Invalid orientation %zd", orientation);
156      return nil;
157  }
158
159  UIGraphicsBeginImageContext(bounds.size);
160  CGContextRef context = UIGraphicsGetCurrentContext();
161
162  switch (orientation) {
163    case UIImageOrientationLeft:
164    case UIImageOrientationLeftMirrored:
165    case UIImageOrientationRight:
166    case UIImageOrientationRightMirrored:
167      CGContextScaleCTM(context, -1.0, 1.0);
168      CGContextTranslateCTM(context, -rect.size.height, 0.0);
169      break;
170
171    default:
172      CGContextScaleCTM(context, 1.0, -1.0);
173      CGContextTranslateCTM(context, 0.0, -rect.size.height);
174      break;
175  }
176
177  CGContextConcatCTM(context, transform);
178  CGContextDrawImage(context, rect, [self CGImage]);
179
180  UIImage *rotatedImage = UIGraphicsGetImageFromCurrentImageContext();
181  UIGraphicsEndImageContext();
182
183  return rotatedImage;
184}
185
186@end