-
Notifications
You must be signed in to change notification settings - Fork 74
/
Copy pathUIImage+Resize.m
153 lines (119 loc) · 5.46 KB
/
UIImage+Resize.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// UIImage+Resize.m
//
// Created by Olivier Halligon on 12/08/09.
// Copyright 2009 AliSoftware. All rights reserved.
//
#import "UIImage+Resize.h"
@implementation UIImage (ResizeCategory)
-(UIImage*)resizedImageToSize:(CGSize)dstSize
{
CGImageRef imgRef = self.CGImage;
// the below values are regardless of orientation : for UIImages from Camera, width>height (landscape)
CGSize srcSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); // not equivalent to self.size (which is dependant on the imageOrientation)!
/* Don't resize if we already meet the required destination size. */
if (CGSizeEqualToSize(srcSize, dstSize)) {
return self;
}
CGFloat scaleRatio = dstSize.width / srcSize.width;
UIImageOrientation orient = self.imageOrientation;
CGAffineTransform transform = CGAffineTransformIdentity;
switch(orient) {
case UIImageOrientationUp: //EXIF = 1
transform = CGAffineTransformIdentity;
break;
case UIImageOrientationUpMirrored: //EXIF = 2
transform = CGAffineTransformMakeTranslation(srcSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
break;
case UIImageOrientationDown: //EXIF = 3
transform = CGAffineTransformMakeTranslation(srcSize.width, srcSize.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationDownMirrored: //EXIF = 4
transform = CGAffineTransformMakeTranslation(0.0, srcSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
break;
case UIImageOrientationLeftMirrored: //EXIF = 5
dstSize = CGSizeMake(dstSize.height, dstSize.width);
transform = CGAffineTransformMakeTranslation(srcSize.height, srcSize.width);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI_2);
break;
case UIImageOrientationLeft: //EXIF = 6
dstSize = CGSizeMake(dstSize.height, dstSize.width);
transform = CGAffineTransformMakeTranslation(0.0, srcSize.width);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI_2);
break;
case UIImageOrientationRightMirrored: //EXIF = 7
dstSize = CGSizeMake(dstSize.height, dstSize.width);
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight: //EXIF = 8
dstSize = CGSizeMake(dstSize.height, dstSize.width);
transform = CGAffineTransformMakeTranslation(srcSize.height, 0.0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
default:
[NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
}
/////////////////////////////////////////////////////////////////////////////
// The actual resize: draw the image on a new context, applying a transform matrix
UIGraphicsBeginImageContextWithOptions(dstSize, NO, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
if (!context) {
return nil;
}
if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
CGContextScaleCTM(context, -scaleRatio, scaleRatio);
CGContextTranslateCTM(context, -srcSize.height, 0);
} else {
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -srcSize.height);
}
CGContextConcatCTM(context, transform);
// we use srcSize (and not dstSize) as the size to specify is in user space (and we use the CTM to apply a scaleRatio)
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, srcSize.width, srcSize.height), imgRef);
UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resizedImage;
}
/////////////////////////////////////////////////////////////////////////////
-(UIImage*)resizedImageToFitInSize:(CGSize)boundingSize scaleIfSmaller:(BOOL)scale
{
// get the image size (independant of imageOrientation)
CGImageRef imgRef = self.CGImage;
CGSize srcSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); // not equivalent to self.size (which depends on the imageOrientation)!
// adjust boundingSize to make it independant on imageOrientation too for farther computations
UIImageOrientation orient = self.imageOrientation;
switch (orient) {
case UIImageOrientationLeft:
case UIImageOrientationRight:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
boundingSize = CGSizeMake(boundingSize.height, boundingSize.width);
break;
default:
// NOP
break;
}
// Compute the target CGRect in order to keep aspect-ratio
CGSize dstSize;
if ( !scale && (srcSize.width < boundingSize.width) && (srcSize.height < boundingSize.height) ) {
//NSLog(@"Image is smaller, and we asked not to scale it in this case (scaleIfSmaller:NO)");
dstSize = srcSize; // no resize (we could directly return 'self' here, but we draw the image anyway to take image orientation into account)
} else {
CGFloat wRatio = boundingSize.width / srcSize.width;
CGFloat hRatio = boundingSize.height / srcSize.height;
if (wRatio < hRatio) {
//NSLog(@"Width imposed, Height scaled ; ratio = %f",wRatio);
dstSize = CGSizeMake(boundingSize.width, floorf(srcSize.height * wRatio));
} else {
//NSLog(@"Height imposed, Width scaled ; ratio = %f",hRatio);
dstSize = CGSizeMake(floorf(srcSize.width * hRatio), boundingSize.height);
}
}
return [self resizedImageToSize:dstSize];
}
@end