diff options
author | gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2010-05-26 18:06:02 +0000 |
---|---|---|
committer | gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2010-05-26 18:06:02 +0000 |
commit | c8b442e4af5f12d91450e9b1fcce1468aa49de4e (patch) | |
tree | 6b4025ace69838de8fedcb96de8db0b0aa14d58a | |
parent | 69491c3dd52dffcb3fdbaffeffb63483fbd15088 (diff) |
[Author: caseyho]
UIImage rotate method plus tests.
R=altse
APPROVED=altse
DELTA=152 (152 added, 0 deleted, 0 changed)
-rw-r--r-- | GTMiPhone.xcodeproj/project.pbxproj | 8 | ||||
-rw-r--r-- | ReleaseNotes.txt | 7 | ||||
-rw-r--r-- | iPhone/GTMUIImage+Resize.h | 11 | ||||
-rw-r--r-- | iPhone/GTMUIImage+Resize.m | 100 | ||||
-rw-r--r-- | iPhone/GTMUIImage+ResizeTest.m | 26 | ||||
-rw-r--r-- | iPhone/TestData/GTMUIImage+Resize_100x50_flipped.png | bin | 0 -> 1178 bytes | |||
-rw-r--r-- | iPhone/TestData/GTMUIImage+Resize_50x100_flipped.png | bin | 0 -> 1197 bytes |
7 files changed, 151 insertions, 1 deletions
diff --git a/GTMiPhone.xcodeproj/project.pbxproj b/GTMiPhone.xcodeproj/project.pbxproj index 842dca2..42e0ec4 100644 --- a/GTMiPhone.xcodeproj/project.pbxproj +++ b/GTMiPhone.xcodeproj/project.pbxproj @@ -32,6 +32,8 @@ 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 448D61FB11AC1F1B0097ACBC /* GTMUIImage+Resize_100x50_flipped.png in Resources */ = {isa = PBXBuildFile; fileRef = 448D61B111AC1AAD0097ACBC /* GTMUIImage+Resize_100x50_flipped.png */; }; + 448D61FC11AC1F250097ACBC /* GTMUIImage+Resize_50x100_flipped.png in Resources */ = {isa = PBXBuildFile; fileRef = 448D61B011AC1AAD0097ACBC /* GTMUIImage+Resize_50x100_flipped.png */; }; 6294461C0EDE178D009295EA /* GTMNSArray+MergeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 629446190EDE177A009295EA /* GTMNSArray+MergeTest.m */; }; 6294461D0EDE17A0009295EA /* GTMNSArray+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = 629446180EDE177A009295EA /* GTMNSArray+Merge.m */; }; 64D0F5C80FD3E65C00506CC7 /* GTMUIImage+ResizeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 64D0F5C60FD3E65C00506CC7 /* GTMUIImage+ResizeTest.m */; }; @@ -157,6 +159,8 @@ 1D6058910D05DD3D006BFB54 /* GTMiPhoneTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GTMiPhoneTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 32CA4F630368D1EE00C91783 /* GTM_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTM_Prefix.pch; sourceTree = "<group>"; }; + 448D61B011AC1AAD0097ACBC /* GTMUIImage+Resize_50x100_flipped.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "GTMUIImage+Resize_50x100_flipped.png"; path = "TestData/GTMUIImage+Resize_50x100_flipped.png"; sourceTree = "<group>"; }; + 448D61B111AC1AAD0097ACBC /* GTMUIImage+Resize_100x50_flipped.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "GTMUIImage+Resize_100x50_flipped.png"; path = "TestData/GTMUIImage+Resize_100x50_flipped.png"; sourceTree = "<group>"; }; 629446170EDE177A009295EA /* GTMNSArray+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSArray+Merge.h"; sourceTree = "<group>"; }; 629446180EDE177A009295EA /* GTMNSArray+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSArray+Merge.m"; sourceTree = "<group>"; }; 629446190EDE177A009295EA /* GTMNSArray+MergeTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSArray+MergeTest.m"; sourceTree = "<group>"; }; @@ -385,6 +389,7 @@ children = ( 64D0F5CC0FD3E68400506CC7 /* GTMUIImage+Resize_100x100_to_60x40.png */, 64D0F5CD0FD3E68400506CC7 /* GTMUIImage+Resize_50x100.png */, + 448D61B011AC1AAD0097ACBC /* GTMUIImage+Resize_50x100_flipped.png */, 64D0F5CE0FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_40x60_clip.png */, 64D0F5CF0FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_40x60_noclip.png */, 64D0F5D00FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_50x50_clip.png */, @@ -392,6 +397,7 @@ 64D0F5D20FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_60x40_clip.png */, 64D0F5D30FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_60x40_noclip.png */, 64D0F5D40FD3E68400506CC7 /* GTMUIImage+Resize_100x50.png */, + 448D61B111AC1AAD0097ACBC /* GTMUIImage+Resize_100x50_flipped.png */, 64D0F5D50FD3E68400506CC7 /* GTMUIImage+Resize_100x50_to_40x60_clip.png */, 64D0F5D60FD3E68400506CC7 /* GTMUIImage+Resize_100x50_to_40x60_noclip.png */, 64D0F5D70FD3E68400506CC7 /* GTMUIImage+Resize_100x50_to_50x50_clip.png */, @@ -698,6 +704,7 @@ 8BFE15C90FB0F764001BE894 /* phone.png in Resources */, 64D0F5DE0FD3E68400506CC7 /* GTMUIImage+Resize_100x100_to_60x40.png in Resources */, 64D0F5DF0FD3E68400506CC7 /* GTMUIImage+Resize_50x100.png in Resources */, + 448D61FC11AC1F250097ACBC /* GTMUIImage+Resize_50x100_flipped.png in Resources */, 64D0F5E00FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_40x60_clip.png in Resources */, 64D0F5E10FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_40x60_noclip.png in Resources */, 64D0F5E20FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_50x50_clip.png in Resources */, @@ -705,6 +712,7 @@ 64D0F5E40FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_60x40_clip.png in Resources */, 64D0F5E50FD3E68400506CC7 /* GTMUIImage+Resize_50x100_to_60x40_noclip.png in Resources */, 64D0F5E60FD3E68400506CC7 /* GTMUIImage+Resize_100x50.png in Resources */, + 448D61FB11AC1F1B0097ACBC /* GTMUIImage+Resize_100x50_flipped.png in Resources */, 64D0F5E70FD3E68400506CC7 /* GTMUIImage+Resize_100x50_to_40x60_clip.png in Resources */, 64D0F5E80FD3E68400506CC7 /* GTMUIImage+Resize_100x50_to_40x60_noclip.png in Resources */, 64D0F5E90FD3E68400506CC7 /* GTMUIImage+Resize_100x50_to_50x50_clip.png in Resources */, diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt index 3225d3a..d2434ae 100644 --- a/ReleaseNotes.txt +++ b/ReleaseNotes.txt @@ -399,7 +399,7 @@ Changes since 1.5.1 - Removed GTMTheme because it wasn't generic enough for inclusion in GTM, and was never fully implemented -- Added GTM_NONNULL, NS_RETURNS_RETAINED, and CF_RETURNS_RETAINED macrs to +- Added GTM_NONNULL, NS_RETURNS_RETAINED, and CF_RETURNS_RETAINED macrs to support clang analysis. - Changed GTMStackTrace to put out a cleaner trace, and to work on 64 bit. @@ -412,6 +412,11 @@ Changes since 1.5.1 - Added GTMNSAnimatablePropertyContainer methods that allow you to stop animations properly in 10.5. +- Added gtm_imageByRotating for rotating a UIImage. 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 + Release 1.5.1 Changes since 1.5.0 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 Binary files differnew file mode 100644 index 0000000..c6b1d8f --- /dev/null +++ b/iPhone/TestData/GTMUIImage+Resize_100x50_flipped.png diff --git a/iPhone/TestData/GTMUIImage+Resize_50x100_flipped.png b/iPhone/TestData/GTMUIImage+Resize_50x100_flipped.png Binary files differnew file mode 100644 index 0000000..bdce5a2 --- /dev/null +++ b/iPhone/TestData/GTMUIImage+Resize_50x100_flipped.png |