From c8b442e4af5f12d91450e9b1fcce1468aa49de4e Mon Sep 17 00:00:00 2001 From: "gtm.daemon" Date: Wed, 26 May 2010 18:06:02 +0000 Subject: [Author: caseyho] UIImage rotate method plus tests. R=altse APPROVED=altse DELTA=152 (152 added, 0 deleted, 0 changed) --- iPhone/GTMUIImage+Resize.h | 11 +++ iPhone/GTMUIImage+Resize.m | 100 +++++++++++++++++++++ iPhone/GTMUIImage+ResizeTest.m | 26 ++++++ .../TestData/GTMUIImage+Resize_100x50_flipped.png | Bin 0 -> 1178 bytes .../TestData/GTMUIImage+Resize_50x100_flipped.png | Bin 0 -> 1197 bytes 5 files changed, 137 insertions(+) create mode 100644 iPhone/TestData/GTMUIImage+Resize_100x50_flipped.png create mode 100644 iPhone/TestData/GTMUIImage+Resize_50x100_flipped.png (limited to 'iPhone') diff --git a/iPhone/GTMUIImage+Resize.h b/iPhone/GTMUIImage+Resize.h index 25e2125..a1d4ed3 100644 --- a/iPhone/GTMUIImage+Resize.h +++ b/iPhone/GTMUIImage+Resize.h @@ -37,4 +37,15 @@ - (UIImage *)gtm_imageByResizingToSize:(CGSize)targetSize preserveAspectRatio:(BOOL)preserveAspectRatio trimToFit:(BOOL)trimToFit; + +// Returns an image rotated by |orientation| where the current orientation is +// taken as UIImageOrientationUp. Nil if |orientation| is invalid. +// +// For example, UIImageOrientationRight is a 90 degree rotation clockwise, +// UIImageOrientationDown is a 180 degree rotation closewise. +// +// Supplying UIImageOrientationUp to |orientation| will return a copy of the +// image. +- (UIImage *)gtm_imageByRotating:(UIImageOrientation)orientation; + @end diff --git a/iPhone/GTMUIImage+Resize.m b/iPhone/GTMUIImage+Resize.m index 9dd2144..49b82c8 100644 --- a/iPhone/GTMUIImage+Resize.m +++ b/iPhone/GTMUIImage+Resize.m @@ -17,6 +17,16 @@ // #import "GTMUIImage+Resize.h" +#import "GTMDefines.h" + +GTM_INLINE CGSize swapWidthAndHeight(CGSize size) { + CGFloat tempWidth = size.width; + + size.width = size.height; + size.height = tempWidth; + + return size; +} @implementation UIImage (GTMUIImageResizeAdditions) @@ -83,4 +93,94 @@ UIGraphicsEndImageContext(); return resizedPhoto; } + +// Based on code by Trevor Harmon: +// http://vocaro.com/trevor/blog/wp-content/uploads/2009/10/UIImage+Resize.h +// http://vocaro.com/trevor/blog/wp-content/uploads/2009/10/UIImage+Resize.m +- (UIImage *)gtm_imageByRotating:(UIImageOrientation)orientation { + CGRect bounds = CGRectZero; + CGRect rect = CGRectZero; + CGAffineTransform transform = CGAffineTransformIdentity; + + bounds.size = [self size]; + rect.size = [self size]; + + switch (orientation) { + case UIImageOrientationUp: + return [UIImage imageWithCGImage:[self CGImage]]; + + case UIImageOrientationUpMirrored: + transform = CGAffineTransformMakeTranslation(rect.size.width, 0.0); + transform = CGAffineTransformScale(transform, -1.0, 1.0); + break; + + case UIImageOrientationDown: + transform = CGAffineTransformMakeTranslation(rect.size.width, + rect.size.height); + transform = CGAffineTransformRotate(transform, M_PI); + break; + + case UIImageOrientationDownMirrored: + transform = CGAffineTransformMakeTranslation(0.0, rect.size.height); + transform = CGAffineTransformScale(transform, 1.0, -1.0); + break; + + case UIImageOrientationLeft: + bounds.size = swapWidthAndHeight(bounds.size); + transform = CGAffineTransformMakeTranslation(0.0, rect.size.width); + transform = CGAffineTransformRotate(transform, -M_PI_2); + break; + + case UIImageOrientationLeftMirrored: + bounds.size = swapWidthAndHeight(bounds.size); + transform = CGAffineTransformMakeTranslation(rect.size.height, + rect.size.width); + transform = CGAffineTransformScale(transform, -1.0, 1.0); + transform = CGAffineTransformRotate(transform, -M_PI_2); + break; + + case UIImageOrientationRight: + bounds.size = swapWidthAndHeight(bounds.size); + transform = CGAffineTransformMakeTranslation(rect.size.height, 0.0); + transform = CGAffineTransformRotate(transform, M_PI_2); + break; + + case UIImageOrientationRightMirrored: + bounds.size = swapWidthAndHeight(bounds.size); + transform = CGAffineTransformMakeScale(-1.0, 1.0); + transform = CGAffineTransformRotate(transform, M_PI_2); + break; + + default: + _GTMDevAssert(false, @"Invalid orientation %d", orientation); + return nil; + } + + UIGraphicsBeginImageContext(bounds.size); + CGContextRef context = UIGraphicsGetCurrentContext(); + + switch (orientation) { + case UIImageOrientationLeft: + case UIImageOrientationLeftMirrored: + case UIImageOrientationRight: + case UIImageOrientationRightMirrored: + CGContextScaleCTM(context, -1.0, 1.0); + CGContextTranslateCTM(context, -rect.size.height, 0.0); + break; + + default: + CGContextScaleCTM(context, 1.0, -1.0); + CGContextTranslateCTM(context, 0.0, -rect.size.height); + break; + } + + CGContextConcatCTM(context, transform); + CGContextDrawImage(context, rect, [self CGImage]); + + UIImage *rotatedImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return rotatedImage; +} + @end diff --git a/iPhone/GTMUIImage+ResizeTest.m b/iPhone/GTMUIImage+ResizeTest.m index 4678511..8318104 100644 --- a/iPhone/GTMUIImage+ResizeTest.m +++ b/iPhone/GTMUIImage+ResizeTest.m @@ -253,4 +253,30 @@ GTMUIImageResizeAssertImageEqual(actual, @"50x100_to_40x60_clip"); } +- (void)testImageByRotating { + UIImage *actual = nil; + UIImage *landscapeImage = + [UIImage imageNamed:@"GTMUIImage+Resize_100x50.png"]; + STAssertNotNil(landscapeImage, @"Unable to read image."); + + // Rotate 90 degrees. + actual = [landscapeImage gtm_imageByRotating:UIImageOrientationRight]; + GTMUIImageResizeAssertImageEqual(actual, @"50x100"); + + // Rotate 180 degrees. + actual = [landscapeImage gtm_imageByRotating:UIImageOrientationDown]; + GTMUIImageResizeAssertImageEqual(actual, + @"100x50_flipped"); + + + // Rotate 270 degrees. + actual = [landscapeImage gtm_imageByRotating:UIImageOrientationLeft]; + GTMUIImageResizeAssertImageEqual(actual, + @"50x100_flipped"); + + // Rotate 360 degrees. + actual = [landscapeImage gtm_imageByRotating:UIImageOrientationUp]; + GTMUIImageResizeAssertImageEqual(actual, @"100x50"); +} + @end diff --git a/iPhone/TestData/GTMUIImage+Resize_100x50_flipped.png b/iPhone/TestData/GTMUIImage+Resize_100x50_flipped.png new file mode 100644 index 0000000..c6b1d8f Binary files /dev/null and b/iPhone/TestData/GTMUIImage+Resize_100x50_flipped.png differ diff --git a/iPhone/TestData/GTMUIImage+Resize_50x100_flipped.png b/iPhone/TestData/GTMUIImage+Resize_50x100_flipped.png new file mode 100644 index 0000000..bdce5a2 Binary files /dev/null and b/iPhone/TestData/GTMUIImage+Resize_50x100_flipped.png differ -- cgit v1.2.3